<!DOCTYPE html>


<html lang="en">


<head>
  <meta charset="utf-8" />
    
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
     
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  
  <link rel="shortcut icon" href="/favicon.ico" />
  
  
<link rel="stylesheet" href="/dist/main.css">

  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">

  
<link rel="stylesheet" href="/css/custom.css">

  
  
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

  
  

  

</head>

</html>

<body>
  <div id="app">
    
      
      <canvas width="1777" height="841"
        style="position: fixed; left: 0px; top: 0px; z-index: 99999; pointer-events: none;"></canvas>
      
    <main class="content on">
      
<section class="cover">
    
  <div class="cover-frame">
    <div class="bg-box">
      <img src="/images/82752296_p0.jpg" alt="image frame" />
    </div>
    <div class="cover-inner text-center text-white">
      <h1><a href="/">Doreen&#39;s Blog</a></h1>
      <div id="subtitle-box">
        
        <span id="subtitle"></span>
        
      </div>
      <div>
        
      </div>
    </div>
  </div>
  <div class="cover-learn-more">
    <a href="javascript:void(0)" class="anchor"><i class="ri-arrow-down-line"></i></a>
  </div>
</section>



<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js"></script>


<!-- Subtitle -->

  <script>
    try {
      var typed = new Typed("#subtitle", {
        strings: ['一切都会好的，城南的花都开了', '今晚的月色真美', '注重过程，别在乎结果'],
        startDelay: 0,
        typeSpeed: 200,
        loop: true,
        backSpeed: 100,
        showCursor: true
      });
    } catch (err) {
      console.log(err)
    }
  </script>
  
<div id="main">
  <section class="outer">
  
  

<div class="notice" style="margin-top:50px">
    <i class="ri-heart-fill"></i>
    <div class="notice-content" id="broad"></div>
</div>
<script type="text/javascript">
    fetch('https://v1.hitokoto.cn')
        .then(response => response.json())
        .then(data => {
            document.getElementById("broad").innerHTML = data.hitokoto;
        })
        .catch(console.error)
</script>

<style>
    .notice {
        padding: 20px;
        border: 1px dashed #e6e6e6;
        color: #969696;
        position: relative;
        display: inline-block;
        width: 100%;
        background: #fbfbfb50;
        border-radius: 10px;
    }

    .notice i {
        float: left;
        color: #999;
        font-size: 16px;
        padding-right: 10px;
        vertical-align: middle;
        margin-top: -2px;
    }

    .notice-content {
        display: initial;
        vertical-align: middle;
    }
</style>
  
  <article class="articles">
    
    
    
    
    <article
  id="post-redux"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/04/16/redux/"
    >redux配合react的简单使用</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/04/16/redux/" class="article-date">
  <time datetime="2020-04-16T04:21:42.000Z" itemprop="datePublished">2020-04-16</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/react/">react</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><blockquote>
<p>javascript状态容器，提供可预测化的状态管理。（类似于vuex）</p>
</blockquote>
<h2 id="redux的工作流程"><a href="#redux的工作流程" class="headerlink" title="redux的工作流程"></a>redux的工作流程</h2><p><img src="http://www.ruanyifeng.com/blogimg/asset/2016/bg2016091802.jpg"></p>
<blockquote>
<p>store 是数据的存放地，组件从store中获取数据<br>action 存放着组件(view)对数据(data)的操作<br>reducer 根据传来的action的类型来更新state</p>
</blockquote>
<h3 id="流程详解"><a href="#流程详解" class="headerlink" title="流程详解"></a>流程详解</h3><ol>
<li><p>用户操作视图数据发出action</p>
<blockquote>
<p>store.dispatch(action)</p>
</blockquote>
</li>
<li><p>store自动调用reducer，并传入两个参数state和action。reducer根据action返回新的state</p>
<blockquote>
<p>(state=defaultState,action)=&gt;{ if(action.type===’…’){ return newState}… }</p>
</blockquote>
</li>
<li><p>state发生变化，store调用监听函数</p>
<blockquote>
<p>store.subscribe(listener)</p>
</blockquote>
</li>
<li><p>listener可以通过store.getState()得到当前状态，重新渲染页面</p>
<blockquote>
<p>function(){<br>   let newState = store.getState()<br>   component.setState(newState)<br>}</p>
</blockquote>
<h2 id="三大原则"><a href="#三大原则" class="headerlink" title="三大原则"></a>三大原则</h2></li>
<li><p>单一数据源<br>整个应用的 state 被储存在一棵 object tree 中，并且这个 object tree 只存在于唯一一个 store 中。</p>
</li>
<li><p>state是只读的<br>唯一改变 state 的方法就是触发 action，action 是一个用于描述已发生事件的普通对象。</p>
</li>
<li><p>使用纯函数来执行修改<br>为了描述 action 如何改变 state tree ，需要编写 reducers。它接收先前的 state 和 action，并返回新的 state。</p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><blockquote>
<p>npm i redux –save</p>
</blockquote>
<h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><p>一般会创建一个单独的文件夹来存放这些数据</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">src</span><br><span class="line"> └── store</span><br><span class="line">       ├── index.js</span><br><span class="line">       ├── reducer.js</span><br><span class="line">       └── actions.js</span><br></pre></td></tr></table></figure>
<h3 id="index-state"><a href="#index-state" class="headerlink" title="index (state)"></a>index (state)</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">createStore()：</span></span><br><span class="line"><span class="comment">创建一个store来存放所有的state</span></span><br><span class="line"><span class="comment">应用中有且仅有一个store</span></span><br><span class="line"><span class="comment">参数</span></span><br><span class="line"><span class="comment">1：reducer(Function)</span></span><br><span class="line"><span class="comment">2：[preloadeState](any): 初始的state</span></span><br><span class="line"><span class="comment">3：enhancer(Function): 强化的store creator ？？</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">import</span> &#123; createStore &#125; <span class="keyword">from</span> <span class="string">&#x27;redux&#x27;</span> <span class="comment">// 引入方法</span></span><br><span class="line"><span class="keyword">import</span> reducer <span class="keyword">from</span> <span class="string">&#x27;./reducer&#x27;</span>     <span class="comment">// 引入reducer</span></span><br><span class="line"><span class="keyword">const</span> store = createStore(          <span class="comment">// 创建存储仓库</span></span><br><span class="line">    reducer, </span><br><span class="line">    <span class="built_in">window</span>.__REDUX_DEVTOOLS_EXTENSION__ &amp;&amp; <span class="built_in">window</span>.__REDUX_DEVTOOLS_EXTENSION__()</span><br><span class="line">)</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> store        <span class="comment">// 把创建好的数据仓库暴露出去</span></span><br></pre></td></tr></table></figure>

</li>
</ol>
<p>在组件中获取数据</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&#x27;./store&#x27;</span>;</span><br><span class="line">...</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">App</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">    <span class="keyword">constructor</span>(props)&#123;</span><br><span class="line">        <span class="built_in">super</span>(props)</span><br><span class="line">        <span class="built_in">this</span>.state = store.getState()   <span class="comment">//获取state</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> App;</span><br></pre></td></tr></table></figure>
<h3 id="actions"><a href="#actions" class="headerlink" title="actions"></a>actions</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// actions.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">addAction</span> = (<span class="params"></span>)=&gt; (<span class="params">&#123;</span></span></span><br><span class="line"><span class="function"><span class="params">    type: <span class="string">&#x27;add&#x27;</span></span></span></span><br><span class="line"><span class="function"><span class="params">&#125;</span>)</span></span><br><span class="line"><span class="function"><span class="title">export</span> <span class="title">function</span> <span class="title">changeInputAction</span> = (<span class="params">value</span>)=&gt;(<span class="params">&#123;</span></span></span><br><span class="line"><span class="function"><span class="params">    type: <span class="string">&#x27;changeInput&#x27;</span>,</span></span></span><br><span class="line"><span class="function"><span class="params">    value</span></span></span><br><span class="line"><span class="function"><span class="params">&#125;</span>)</span></span><br></pre></td></tr></table></figure>

<p>在组件内使用action</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;changeInputAction,addAction&#125; <span class="keyword">from</span> <span class="string">&#x27;./store/actions&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">App</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 触发事件就会触发action</span></span><br><span class="line">  changeInputValue(e)&#123;</span><br><span class="line">    <span class="keyword">const</span> action = changeInputAction(e.target.value)</span><br><span class="line">    store.dispatch(action)  <span class="comment">// 更新state</span></span><br><span class="line">  &#125;</span><br><span class="line">  add()&#123;</span><br><span class="line">    <span class="keyword">const</span> action = addAction()</span><br><span class="line">    store.dispatch(action)</span><br><span class="line">  &#125;</span><br><span class="line">  storeChange()&#123;</span><br><span class="line">    <span class="built_in">this</span>.setState(store.getState())</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> App;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="reducer"><a href="#reducer" class="headerlink" title="reducer"></a>reducer</h3><p>它没有直接改变state的数据，而是返回新的对象</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建初始的state数据</span></span><br><span class="line"><span class="keyword">const</span> defaultState = &#123;</span><br><span class="line">    list:[<span class="string">&#x27;hehe&#x27;</span>,<span class="string">&#x27;enen&#x27;</span>],</span><br><span class="line">    inputValue:<span class="string">&#x27;write somthing&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> (state=defaultState,action)=&gt;&#123;</span><br><span class="line">    <span class="keyword">if</span>(action.type===<span class="string">&#x27;changeInput&#x27;</span>)&#123;</span><br><span class="line">        <span class="keyword">let</span> newState = <span class="built_in">JSON</span>.parse(<span class="built_in">JSON</span>.stringify(state))    <span class="comment">// 深拷贝</span></span><br><span class="line">        newState.inputValue = action.value  <span class="comment">// 更新数据</span></span><br><span class="line">        <span class="keyword">return</span> newState <span class="comment">// 返回新的state</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(action.type===<span class="string">&#x27;add&#x27;</span>)&#123;</span><br><span class="line">        <span class="keyword">let</span> newState = <span class="built_in">JSON</span>.parse(<span class="built_in">JSON</span>.stringify(state))</span><br><span class="line">        newState.list.push(newState.inputValue)</span><br><span class="line">        newState.inputValue = <span class="string">&#x27;&#x27;</span></span><br><span class="line">        <span class="keyword">return</span> newState</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> state</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 官方文档给出的代码段 是用switch-case进行对action类型的判断，assign进行拷贝和更新：</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">todoApp</span>(<span class="params">state = defaultState, action</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">switch</span> (action.type) &#123;</span><br><span class="line">    <span class="keyword">case</span> SET_VISIBILITY_FILTER:</span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">Object</span>.assign(&#123;&#125;, state, &#123;</span><br><span class="line">        visibilityFilter: action.filter</span><br><span class="line">      &#125;)</span><br><span class="line">    <span class="keyword">case</span> ADD_TODO:</span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">Object</span>.assign(&#123;&#125;, state, &#123;</span><br><span class="line">        todos: [</span><br><span class="line">          ...state.todos,</span><br><span class="line">          &#123;</span><br><span class="line">            text: action.text,</span><br><span class="line">            completed: <span class="literal">false</span></span><br><span class="line">          &#125;</span><br><span class="line">        ]</span><br><span class="line">      &#125;)</span><br><span class="line">    <span class="keyword">default</span>:</span><br><span class="line">      <span class="keyword">return</span> state</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a target="_blank" rel="noopener" href="https://www.redux.org.cn/">redux中文文档</a><br><a target="_blank" rel="noopener" href="https://jspang.com/detailed?id=48#toc218">技术胖博客</a></p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-react01"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/04/10/react01/"
    >【react】开发环境搭建</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/04/10/react01/" class="article-date">
  <time datetime="2020-04-10T04:21:42.000Z" itemprop="datePublished">2020-04-10</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/react/">react</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="首先安装-Node-和-npm"><a href="#首先安装-Node-和-npm" class="headerlink" title="首先安装 Node 和 npm"></a>首先安装 Node 和 npm</h2><p>我的版本 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">node v10.15</span><br><span class="line">npm v6.4.1</span><br></pre></td></tr></table></figure>
<h2 id="创建应用程序"><a href="#创建应用程序" class="headerlink" title="创建应用程序"></a>创建应用程序</h2><ol>
<li>针对于npm 5.2+<blockquote>
<p>npx create-react-app xxx</p>
</blockquote>
</li>
<li>针对于npm 6+<blockquote>
<p>npm init react-app xxx</p>
</blockquote>
</li>
<li>针对于yarn 0.25+<blockquote>
<p>yarn create react-app xxx</p>
</blockquote>
</li>
</ol>
<h2 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h2><p>进入到xxx目录中，应该生成的目录格式如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">xxx</span><br><span class="line">├── README.md</span><br><span class="line">├── node_modules</span><br><span class="line">├── package.json</span><br><span class="line">├── .gitignore</span><br><span class="line">├── public</span><br><span class="line">│   ├── favicon.ico</span><br><span class="line">│   ├── index.html</span><br><span class="line">│   └── manifest.json</span><br><span class="line">└── src</span><br><span class="line">    ├── App.css</span><br><span class="line">    ├── App.js</span><br><span class="line">    ├── App.test.js</span><br><span class="line">    ├── index.css</span><br><span class="line">    ├── index.js</span><br><span class="line">    ├── logo.svg</span><br><span class="line">    └── serviceWorker.js</span><br></pre></td></tr></table></figure>
<p>安装完成后，即可进入到项目目录：</p>
<blockquote>
<p>cd xxx</p>
</blockquote>
<h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><ol>
<li>运行：<blockquote>
<p>npm start</p>
</blockquote>
</li>
<li>打包：<blockquote>
<p>npm run build</p>
</blockquote>
</li>
</ol>
<h2 id="遇到的问题"><a href="#遇到的问题" class="headerlink" title="遇到的问题"></a>遇到的问题</h2><p>按照文档的方式安装运行脚手架工具报错,并且生成的文件缺失<br>报错信息如下：</p>
<blockquote>
<p>A template was not provided. This is likely because you’re using an outdated version of create-react-app.<br>Please note that global installs of create-react-app are no longer supported.  </p>
</blockquote>
<p>（大概意思是 官方不支持 create-react-app 这个 cli 脚手架，版本已经过时，不支持全局安装）<br>因为我之前也有看过react的相关视频 可能安装的有之前的脚手架版本</p>
<h2 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h2><p>卸载全局安装的脚手架</p>
<blockquote>
<p>npm uninstall -g create-react-app<br>然后在重新按照之前的步骤在运行一次</p>
</blockquote>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-ES2020新特性"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/04/09/ES2020%E6%96%B0%E7%89%B9%E6%80%A7/"
    >ES2020新特性</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/04/09/ES2020%E6%96%B0%E7%89%B9%E6%80%A7/" class="article-date">
  <time datetime="2020-04-09T04:21:42.000Z" itemprop="datePublished">2020-04-09</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/JavaScript/">JavaScript</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>不是所有的都会记录 只记录一些我目前能理解的和我觉得比较有用的</p>
</blockquote>
<h2 id="类的私有变量和方法"><a href="#类的私有变量和方法" class="headerlink" title="类的私有变量和方法"></a>类的私有变量和方法</h2><blockquote>
<p>通过 # 代表私有变量和方法，在class外部无法访问 （相当于private）</p>
</blockquote>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Num</span></span>&#123;</span><br><span class="line">    #privateNum = 0     //私有变量</span><br><span class="line">    static #privateStaticNum = 0        //静态私有变量</span><br><span class="line">    add()&#123;</span><br><span class="line">        this.#privateNum++</span><br><span class="line">        Num.#privateStaticNum++</span><br><span class="line">    &#125;</span><br><span class="line">    print()&#123;</span><br><span class="line">        console.log(this.#privateNum,Num.#privateStaticNum)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> Num()</span><br><span class="line">a.add()</span><br><span class="line">a.print()   <span class="comment">// 1 1</span></span><br><span class="line">console.log(a.#privateNum)     // SyntaxError</span><br><span class="line">console.log(Num.#privateStaticNum)       // SyntaxError</span><br></pre></td></tr></table></figure>
<blockquote>
<p>在MDN和其他的一些大佬的总结里面也写了可以定义私有方法</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">  类似于以这种形式</span></span><br><span class="line"><span class="comment">  不知道是什么原因会报错 unexpected token</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Method</span>()</span>&#123;</span><br><span class="line">    #privateStaticMethod()&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;hello world&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">    publicStaticMethod()&#123;</span><br><span class="line">        return #privateStaticMethod()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* </span></span><br><span class="line"><span class="comment">       另外看到有人总结是用这种形式</span></span><br><span class="line"><span class="comment">       可以正常运行 但是我感觉这种形式就是私有变量的定义赋给一个函数而已？</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    #privateStaticMethod = ()=&gt;&#123; ... &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="空值合并运算符（Nullish-coalescing-Operator）"><a href="#空值合并运算符（Nullish-coalescing-Operator）" class="headerlink" title="空值合并运算符（Nullish coalescing Operator）"></a>空值合并运算符（Nullish coalescing Operator）</h2><blockquote>
<p>和 || 的作用类似，但是 || 会将空字符串、0、false等直接覆盖，可能会造成一些问题，<br>?? 运算符只针对 null、undefined 进行覆盖</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> b = <span class="string">&#x27;&#x27;</span> || <span class="number">123</span>     <span class="comment">// 123</span></span><br><span class="line"><span class="keyword">const</span> a = <span class="string">&#x27;&#x27;</span> ?? <span class="number">123</span>     <span class="comment">// &#x27;&#x27;</span></span><br></pre></td></tr></table></figure>
<h2 id="可选链（Optional-chaining）"><a href="#可选链（Optional-chaining）" class="headerlink" title="可选链（Optional chaining）"></a>可选链（Optional chaining）</h2><blockquote>
<p>简化繁琐重复的前置校验操作</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> user = &#123;</span><br><span class="line">    info: &#123;</span><br><span class="line">        name: &#123;</span><br><span class="line">            getName: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="string">&#x27;doreen&#x27;</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> names = user &amp;&amp; user.info &amp;&amp; user.info.name &amp;&amp; user.info.name.getName &amp;&amp;  user.info.name.getName()</span><br><span class="line"><span class="keyword">let</span> name = user?.info?.name?.getName?.()    <span class="comment">// =&gt;  user?.info?.name?.getName()</span></span><br></pre></td></tr></table></figure>
<h2 id="dynamic-import"><a href="#dynamic-import" class="headerlink" title="dynamic-import"></a>dynamic-import</h2><blockquote>
<p>之前的按需引入是静态import、目前更新的是动态的import()  </p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 用法区别：static import没有括号，dynamic import() 带有括号</span></span><br><span class="line"><span class="comment">// static import : 有声明提升、一般放在头部位置</span></span><br><span class="line"><span class="keyword">import</span> name <span class="keyword">from</span> <span class="string">&#x27;url&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// dynamic import : 放在任意位置</span></span><br><span class="line"><span class="keyword">const</span> name = <span class="keyword">import</span>(<span class="string">&#x27;url&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> test.js:</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">export &#123;xxx&#125;    引入的时候 import &#123;xxx&#125; from &#x27;xxx&#x27; 可以有多个</span></span><br><span class="line"><span class="comment">export default function()&#123;...&#125;  / export default &#123; a()&#123;...&#125;,b()&#123;...&#125; &#125;  </span></span><br><span class="line"><span class="comment">引入的时候 import xxx from &#x27;xxx&#x27;  只能写一次</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">const</span> add = <span class="function">(<span class="params">n,m</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> n+m</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">export</span> &#123; add &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// a.js:</span></span><br><span class="line"><span class="comment">// import()相当于一个promise的实例对象</span></span><br><span class="line"><span class="keyword">const</span> doAdd = <span class="keyword">async</span> (n,m)=&gt;&#123;</span><br><span class="line">    <span class="keyword">const</span> foo = <span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">&#x27;./test.js&#x27;</span>)</span><br><span class="line">    <span class="built_in">console</span>.log(foo.add(n,m))</span><br><span class="line">&#125; </span><br><span class="line"><span class="keyword">const</span> doAdd = <span class="function">(<span class="params">n,m</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">import</span>(<span class="string">&#x27;./test.js&#x27;</span>).then(<span class="function"><span class="params">res</span>=&gt;</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(res.add(n,m))</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line">doAdd(<span class="number">1</span>,<span class="number">2</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="globalThis"><a href="#globalThis" class="headerlink" title="globalThis"></a>globalThis</h2><blockquote>
<p>提供了一个标准的方式去获取不同环境下的全局对象(gloabl、window)<br>在web下能正常打印，但是在node下还是不能正常输出？</p>
</blockquote>
<h2 id="参考："><a href="#参考：" class="headerlink" title="参考："></a>参考：</h2><p><a target="_blank" rel="noopener" href="https://blog.csdn.net/duyujian706709149/article/details/104014127">https://blog.csdn.net/duyujian706709149/article/details/104014127</a><br><a target="_blank" rel="noopener" href="https://segmentfault.com/a/1190000022006869">https://segmentfault.com/a/1190000022006869</a><br><a target="_blank" rel="noopener" href="https://www.jb51.net/article/178289.htm">https://www.jb51.net/article/178289.htm</a><br><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Class_elements">MDN</a></p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-table"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/02/27/table/"
    >JavaScript实现文本编辑器 【table相关操作】</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/02/27/table/" class="article-date">
  <time datetime="2020-02-27T02:16:00.000Z" itemprop="datePublished">2020-02-27</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/JavaScript/">JavaScript</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <pre>
  我自己写的基本操作可以实现
  就是table结构改变了之后 在操作会出现一些问题
  目前没想通要怎么处理 
  查了下看到一个大佬用jQuery写的合并拆分
  基本把我的一些bug解决了 但是我没有看懂他的逻辑QAQ
</pre>
<h2 id="页面结构"><a href="#页面结构" class="headerlink" title="页面结构"></a>页面结构</h2><blockquote>
<p>table的底部和侧边有一个  +  号标记可以添加行/列</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;delTable()&quot;</span>&gt;</span>delete<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;addCell()&quot;</span>&gt;</span>addCell<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;addRow()&quot;</span>&gt;</span>addRow<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;mergeTable()&quot;</span>&gt;</span>合并单元格<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;mergeDown()&quot;</span>&gt;</span>向下合并单元格<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;mergeRight()&quot;</span>&gt;</span>向右合并单元格<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">&quot;splitTable()&quot;</span>&gt;</span>拆分单元格<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">br</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;container&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;table&quot;</span>  <span class="attr">contentEditable</span>=<span class="string">&#x27;true&#x27;</span> &gt;</span></span><br><span class="line">			<span class="tag">&lt;<span class="name">table</span> <span class="attr">border</span>=<span class="string">&quot;1&quot;</span> <span class="attr">id</span>=<span class="string">&quot;table&quot;</span>&gt;</span></span><br><span class="line">				...</span><br><span class="line">			<span class="tag">&lt;/<span class="name">table</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;addCell&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;addCell()&quot;</span>&gt;</span>+<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&#x27;addRow&#x27;</span> <span class="attr">onclick</span>=<span class="string">&quot;addRow()&quot;</span>&gt;</span>+<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h2 id="删除功能"><a href="#删除功能" class="headerlink" title="删除功能"></a>删除功能</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">  delTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="built_in">this</span>.table.remove() <span class="comment">//dom自带方法</span></span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
<h2 id="添加列功能"><a href="#添加列功能" class="headerlink" title="添加列功能"></a>添加列功能</h2><h3 id="trObject-insertCell-index"><a href="#trObject-insertCell-index" class="headerlink" title="trObject.insertCell( index )"></a><a target="_blank" rel="noopener" href="https://www.runoob.com/jsref/met-tablerow-insertcell.html">trObject.insertCell( index )</a></h3><p>insertCell() 方法用于在 HTML 表的一行的指定位置插入一个空的 &lt;td&gt; 元素。<br>新单元格将被插入当前位于 index 指定位置的表元之前。如果 index 等于行中的单元格数，则新单元格被附加在行的末尾。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   *  insertCell( index ) table的原生方法,参数传的是添加的位置</span></span><br><span class="line"><span class="comment">   * 需要注意的是添加之后要重新给列表宽度赋值</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  addCell: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; table.rows.length; i++) &#123;</span><br><span class="line">		<span class="keyword">var</span> newCell = table.rows[i].insertCell(<span class="built_in">this</span>.table.colspan)</span><br><span class="line">		newCell.innerHTML = <span class="string">&#x27;new add&#x27;</span></span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="number">0</span>; j &lt; table.rows[i].cells.length; j++) &#123;</span><br><span class="line">			<span class="built_in">this</span>.table.rows[i].cells[j].style.width = <span class="number">900</span> / <span class="built_in">this</span>.table.rows[<span class="number">0</span>].cells.length + <span class="number">1</span> + <span class="string">&#x27;px&#x27;</span></span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
<h2 id="添加行功能"><a href="#添加行功能" class="headerlink" title="添加行功能"></a>添加行功能</h2><h3 id="tableObject-insertRow-index"><a href="#tableObject-insertRow-index" class="headerlink" title="tableObject.insertRow( index )"></a><a target="_blank" rel="noopener" href="https://www.runoob.com/jsref/met-table-insertrow.html">tableObject.insertRow( index )</a></h3><p>insertRow() 方法用于在表格中的指定位置插入一个新行。<br>index : 指定插入新行的位置 (以 0 开始)。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 被注释的那一段的想法是 在哪点击了就以点击的那一行为模板 在那行下面添加该行内容</span></span><br><span class="line"><span class="comment">   * 但是右侧的添加行功能 不能实现这一操作 就直接获取的第一行的内容来添加 </span></span><br><span class="line"><span class="comment">   * 应该是有bug的</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  addRow: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> newRow = <span class="built_in">this</span>.table.insertRow(<span class="built_in">this</span>.table.rowspan)</span><br><span class="line">	newRow.innerHTML = <span class="built_in">this</span>.table.rows[<span class="number">0</span>].innerHTML <span class="comment">//document.getSelection().getRangeAt(0).startContainer.parentNode.innerHTML</span></span><br><span class="line">&#125;, </span><br></pre></td></tr></table></figure>
<h2 id="合并功能"><a href="#合并功能" class="headerlink" title="合并功能"></a>合并功能</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br></pre></td><td class="code"><pre><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 这个是我写的 直接获取选中的td 然后替换删除</span></span><br><span class="line"><span class="comment">   * 没有考虑到已经合并的情况 是有问题的</span></span><br><span class="line"><span class="comment"> * 我的想法是获取带有选中类的节点，创建一个新的节点 去替换</span></span><br><span class="line"><span class="comment"> * 其余的选中的节点自己删除</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  mergeTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> nodes = <span class="built_in">this</span>.table.getElementsByClassName(<span class="string">&#x27;ui-selected&#x27;</span>)</span><br><span class="line">	<span class="keyword">var</span> newNode = <span class="built_in">document</span>.createElement(<span class="string">&#x27;td&#x27;</span>)</span><br><span class="line">	<span class="keyword">var</span> parent = nodes[<span class="number">0</span>].parentNode</span><br><span class="line">	newNode.rowSpan = <span class="built_in">this</span>.table.rowspan</span><br><span class="line">	newNode.colSpan = <span class="built_in">this</span>.table.colspan</span><br><span class="line">	parent.replaceChild(newNode, nodes[<span class="number">0</span>])</span><br><span class="line">	<span class="keyword">while</span> (nodes[<span class="number">0</span>]) &#123;</span><br><span class="line">		nodes[<span class="number">0</span>].remove()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 这个是CSDN某大佬借助jquery写的 我没看懂QAQ</span></span><br><span class="line"><span class="comment">   * 原文地址 2楼： https://bbs.csdn.net/topics/391807641 </span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  mergeTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> $t = $(<span class="string">&quot;#&quot;</span> + <span class="built_in">this</span>.tableId);</span><br><span class="line">	<span class="keyword">if</span> ($(<span class="string">&quot;table&quot;</span>, $t).length &gt; <span class="number">0</span>) &#123;</span><br><span class="line">		alert(<span class="string">&quot;不支持嵌套表格！&quot;</span>);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">var</span> sigDel = <span class="string">&quot;sign4delete&quot;</span>; <span class="comment">// 删除标记，用作类名</span></span><br><span class="line">	<span class="keyword">var</span> sigSel = <span class="string">&quot;ui-selected&quot;</span>; <span class="comment">// 选中标记，用作类名</span></span><br><span class="line"></span><br><span class="line">	<span class="comment">// 补充单元格以便后继正确计算坐标</span></span><br><span class="line">	$(<span class="string">&quot;th,td&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">		<span class="comment">// 坐标要实时计算，因会实时补充</span></span><br><span class="line">		<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">		<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line"></span><br><span class="line">		<span class="keyword">var</span> rowspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;rowspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">		<span class="keyword">var</span> colspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;colspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">		<span class="keyword">var</span> isSel = $(<span class="built_in">this</span>).hasClass(sigSel);</span><br><span class="line">		<span class="comment">// 非选单元格拆出的单元格要加删除标记</span></span><br><span class="line">		<span class="keyword">if</span> (rowspan &lt;= <span class="number">1</span> &amp;&amp; colspan &lt;= <span class="number">1</span>)</span><br><span class="line">			<span class="keyword">return</span>;</span><br><span class="line">		<span class="comment">// 跨格开插</span></span><br><span class="line">		$(<span class="string">&quot;tr&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> idx = $(<span class="string">&quot;tr&quot;</span>, $t).index(<span class="built_in">this</span>);</span><br><span class="line">			<span class="keyword">var</span> arr, $td = $(<span class="string">&quot;&lt;td&gt;&quot;</span>).addClass(isSel ? sigSel : sigDel);</span><br><span class="line"></span><br><span class="line">			<span class="keyword">if</span> (idx == ridx) &#123;</span><br><span class="line">				<span class="comment">// 本行在 [cidx] 后插入 colspan-1 个</span></span><br><span class="line"></span><br><span class="line">				arr = $(); <span class="comment">// 准备待插单元格</span></span><br><span class="line">				<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; colspan - <span class="number">1</span>; i++)</span><br><span class="line">					arr = arr.add($td.clone());</span><br><span class="line">				<span class="comment">// 插入</span></span><br><span class="line">				$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).after(arr);</span><br><span class="line"></span><br><span class="line">			&#125; <span class="keyword">else</span> <span class="keyword">if</span> (ridx &lt; idx &amp;&amp; idx &lt; ridx + rowspan) &#123;</span><br><span class="line">				<span class="comment">// 以下行在 [cidx] 前插入 colspan 个</span></span><br><span class="line"></span><br><span class="line">				arr = $(); <span class="comment">// 准备待插单元格</span></span><br><span class="line">				<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; colspan; i++)</span><br><span class="line">					arr = arr.add($td.clone());</span><br><span class="line">				<span class="comment">// 插入</span></span><br><span class="line">				<span class="keyword">if</span> (cidx &gt; <span class="number">0</span> &amp;&amp; $(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).length &gt; <span class="number">0</span>)</span><br><span class="line">					$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).after(arr);</span><br><span class="line">				<span class="keyword">else</span> <span class="keyword">if</span> ($(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).length &gt; <span class="number">0</span>)</span><br><span class="line">					$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).before(arr);</span><br><span class="line">				<span class="keyword">else</span></span><br><span class="line">					$(<span class="built_in">this</span>).prepend(arr);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;);</span><br><span class="line">	&#125;);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">var</span> rmin = <span class="number">10000</span>,</span><br><span class="line">		cmin = <span class="number">10000</span>;</span><br><span class="line">	<span class="keyword">var</span> rmax = <span class="number">0</span>,</span><br><span class="line">		cmax = <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">var</span> rnum, cnum;</span><br><span class="line">	<span class="comment">// 计算起始和跨距</span></span><br><span class="line">	$(<span class="string">&quot;th,td&quot;</span>, $t).filter(<span class="string">&quot;.&quot;</span> + sigSel).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">		<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">		rmin = ridx &lt; rmin ? ridx : rmin;</span><br><span class="line">		rmax = ridx &gt; rmax ? ridx : rmax;</span><br><span class="line">		<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line">		cmin = cidx &lt; cmin ? cidx : cmin;</span><br><span class="line">		cmax = cidx &gt; cmax ? cidx : cmax;</span><br><span class="line">	&#125;);</span><br><span class="line">	rnum = rmax - rmin + <span class="number">1</span>;</span><br><span class="line">	cnum = cmax - cmin + <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 合并单元格</span></span><br><span class="line">	$(<span class="string">&quot;th,td&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">		<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">		<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line">		<span class="comment">// 标记单元格待删</span></span><br><span class="line">		<span class="keyword">if</span> (rmin &lt;= ridx &amp;&amp; ridx &lt;= rmax &amp;&amp;</span><br><span class="line">			cmin &lt;= cidx &amp;&amp; cidx &lt;= cmax)</span><br><span class="line">			$(<span class="built_in">this</span>).addClass(sigDel);</span><br><span class="line">		<span class="comment">// 处理被选左上角单元格</span></span><br><span class="line">		<span class="keyword">if</span> (ridx == rmin &amp;&amp; cidx == cmin)</span><br><span class="line">			$(<span class="built_in">this</span>).removeClass(sigDel).attr(&#123;</span><br><span class="line">				rowspan: rnum,</span><br><span class="line">				colspan: cnum</span><br><span class="line">			&#125;);</span><br><span class="line">		<span class="comment">// 清理残余</span></span><br><span class="line">		<span class="keyword">if</span> ($(<span class="built_in">this</span>).attr(<span class="string">&quot;rowspan&quot;</span>) == <span class="number">1</span>) $(<span class="built_in">this</span>).removeAttr(<span class="string">&quot;rowspan&quot;</span>);</span><br><span class="line">		<span class="keyword">if</span> ($(<span class="built_in">this</span>).attr(<span class="string">&quot;colspan&quot;</span>) == <span class="number">1</span>) $(<span class="built_in">this</span>).removeAttr(<span class="string">&quot;colspan&quot;</span>);</span><br><span class="line">	&#125;).remove(<span class="string">&quot;.&quot;</span> + sigDel);</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
<h2 id="向下合并功能"><a href="#向下合并功能" class="headerlink" title="向下合并功能"></a>向下合并功能</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">  mergeDown: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> row = <span class="built_in">document</span>.getSelection().anchorNode.parentNode.rowIndex</span><br><span class="line">	<span class="keyword">var</span> cell = <span class="built_in">document</span>.getSelection().anchorNode.cellIndex</span><br><span class="line">	<span class="keyword">var</span> node = <span class="built_in">document</span>.getSelection().anchorNode</span><br><span class="line">	<span class="keyword">if</span> (row != <span class="built_in">this</span>.table.rows.length - <span class="number">1</span> &amp;&amp; node.rowSpan == <span class="number">1</span>) &#123;</span><br><span class="line">		node.rowSpan = <span class="number">2</span></span><br><span class="line">		<span class="built_in">this</span>.table.rows[row + <span class="number">1</span>].cells[cell].remove()</span><br><span class="line">	&#125;</span><br><span class="line">&#125;,    </span><br></pre></td></tr></table></figure>
<h2 id="向右合并功能"><a href="#向右合并功能" class="headerlink" title="向右合并功能"></a>向右合并功能</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">  mergeRight: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> cell = <span class="built_in">document</span>.getSelection().anchorNode.cellIndex</span><br><span class="line">	<span class="keyword">var</span> node = <span class="built_in">document</span>.getSelection().anchorNode</span><br><span class="line">	<span class="keyword">if</span> (cell != <span class="number">0</span> &amp;&amp; node.colSpan == <span class="number">1</span>) &#123;</span><br><span class="line">		node.previousElementSibling.remove()</span><br><span class="line">		node.colSpan = <span class="number">2</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
<h2 id="拆分功能"><a href="#拆分功能" class="headerlink" title="拆分功能"></a>拆分功能</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br></pre></td><td class="code"><pre><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 我实现的 因为在ueditor里面是只可以拆分两格的</span></span><br><span class="line"><span class="comment">   * 我就按照它的写的 只能拆分两格的</span></span><br><span class="line"><span class="comment">   * 但是多格拆分应该也差不多</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> splitTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> node = <span class="built_in">document</span>.getSelection().anchorNode</span><br><span class="line">	<span class="keyword">var</span> td = <span class="built_in">document</span>.createElement(<span class="string">&#x27;td&#x27;</span>)</span><br><span class="line">	<span class="keyword">if</span> (node.rowSpan == <span class="number">2</span> &amp;&amp; node.colSpan == <span class="number">1</span>) &#123;</span><br><span class="line">		node.rowSpan = <span class="number">1</span></span><br><span class="line">		node.parentNode.nextElementSibling.appendChild(td)</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (node.colSpan == <span class="number">2</span> &amp;&amp; node.rowSpan == <span class="number">1</span>) &#123;</span><br><span class="line">		node.colSpan = <span class="number">1</span></span><br><span class="line">		node.parentNode.appendChild(td)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 也是那个大佬的代码 可以拆分多个单元格</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">  splitTable: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">	<span class="keyword">var</span> $t = $(<span class="string">&quot;#&quot;</span>+<span class="built_in">this</span>.tableId);</span><br><span class="line">		</span><br><span class="line">		<span class="keyword">if</span> ($(<span class="string">&quot;table&quot;</span>, $t).length &gt; <span class="number">0</span>) &#123;</span><br><span class="line">			alert(<span class="string">&quot;不支持嵌套表格！&quot;</span>);</span><br><span class="line">			<span class="keyword">return</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		</span><br><span class="line">		<span class="keyword">var</span> sigDel = <span class="string">&quot;sign4delete&quot;</span>;  <span class="comment">// 删除标记，类名，自定义</span></span><br><span class="line">		<span class="keyword">var</span> sigSel = <span class="string">&quot;ui-selected&quot;</span>;  <span class="comment">// 选中标记，类名，jQuery UI 定义</span></span><br><span class="line">		</span><br><span class="line">		<span class="comment">// 补充单元格以便后继正确计算坐标</span></span><br><span class="line">		$(<span class="string">&quot;th,td&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">			<span class="comment">// 坐标要实时计算，因会实时补充</span></span><br><span class="line">			<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">			<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line">			<span class="keyword">var</span> rowspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;rowspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">			<span class="keyword">var</span> colspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;colspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">			<span class="keyword">var</span> isSel = $(<span class="built_in">this</span>).hasClass(sigSel);</span><br><span class="line">			<span class="comment">// 非选单元格拆出的单元格要加删除标记</span></span><br><span class="line">			</span><br><span class="line">			<span class="keyword">if</span> (rowspan &lt;= <span class="number">1</span> &amp;&amp; colspan &lt;= <span class="number">1</span>)</span><br><span class="line">				<span class="keyword">return</span>;</span><br><span class="line">			</span><br><span class="line">			<span class="keyword">if</span> (isSel)</span><br><span class="line">				$(<span class="built_in">this</span>).removeAttr(<span class="string">&quot;colspan&quot;</span>).removeAttr(<span class="string">&quot;rowspan&quot;</span>);</span><br><span class="line">			</span><br><span class="line">			<span class="comment">// 跨格开插</span></span><br><span class="line">			$(<span class="string">&quot;tr&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">				<span class="keyword">var</span> idx = $(<span class="string">&quot;tr&quot;</span>, $t).index(<span class="built_in">this</span>);</span><br><span class="line">				<span class="keyword">var</span> arr, $td = $(<span class="string">&quot;&lt;td&gt;&quot;</span>);</span><br><span class="line">				</span><br><span class="line">				<span class="keyword">if</span> (!isSel)</span><br><span class="line">					$td.addClass(sigDel);</span><br><span class="line">				</span><br><span class="line">				<span class="keyword">if</span> (idx == ridx) &#123;</span><br><span class="line">					<span class="comment">// 本行在 [cidx] 后插入 colspan-1 个</span></span><br><span class="line">					</span><br><span class="line">					arr = $();  <span class="comment">// 准备待插单元格</span></span><br><span class="line">					<span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>; i &lt; colspan<span class="number">-1</span>; i++)</span><br><span class="line">						arr = arr.add($td.clone());</span><br><span class="line">					</span><br><span class="line">					$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).after(arr);</span><br><span class="line">					</span><br><span class="line">				&#125; <span class="keyword">else</span> <span class="keyword">if</span> (ridx &lt; idx &amp;&amp; idx &lt; ridx + rowspan) &#123;</span><br><span class="line">					<span class="comment">// 以下行在 [cidx] 前插入 colspan 个</span></span><br><span class="line">					</span><br><span class="line">					arr = $();  <span class="comment">// 准备待插单元格</span></span><br><span class="line">					<span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>; i &lt; colspan; i++)</span><br><span class="line">						arr = arr.add($td.clone());</span><br><span class="line">					</span><br><span class="line">					<span class="keyword">if</span> (cidx &gt; <span class="number">0</span> &amp;&amp; $(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).length &gt; <span class="number">0</span>)</span><br><span class="line">						$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).after(arr);</span><br><span class="line">					<span class="keyword">else</span> <span class="keyword">if</span> ($(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).length &gt; <span class="number">0</span>)</span><br><span class="line">						$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).before(arr);</span><br><span class="line">					<span class="keyword">else</span></span><br><span class="line">						$(<span class="built_in">this</span>).prepend(arr);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;);</span><br><span class="line">		&#125;);</span><br><span class="line">		</span><br><span class="line">		<span class="comment">// 重新获取以取到删者并删之</span></span><br><span class="line">		$(<span class="string">&quot;th,td&quot;</span>, $t).remove(<span class="string">&quot;.&quot;</span> + sigDel);</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h2 id="鼠标长按选中事件"><a href="#鼠标长按选中事件" class="headerlink" title="鼠标长按选中事件"></a>鼠标长按选中事件</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line">   <span class="comment">/**</span></span><br><span class="line"><span class="comment">    * 点击选取范围那还是有问题的不知道怎么解决</span></span><br><span class="line"><span class="comment">    * 主要是针对已经合并的单元格 怎么遍历的问题</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">   <span class="built_in">this</span>.table.onmousedown = <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">	<span class="comment">// 鼠标按下的时候获取所在单元格的坐标，和鼠标按下的时间</span></span><br><span class="line">	<span class="built_in">this</span>.startRow = e.target.parentNode.rowIndex</span><br><span class="line">	<span class="built_in">this</span>.startCell = e.target.cellIndex</span><br><span class="line">	<span class="built_in">this</span>.startDate = <span class="keyword">new</span> <span class="built_in">Date</span>()</span><br><span class="line">   &#125;</span><br><span class="line">   </span><br><span class="line">   <span class="built_in">this</span>.table.onmouseup = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="comment">// 通过和鼠标抬起事件所获取的时间进行对比 判断是否是长按鼠标事件</span></span><br><span class="line">	<span class="keyword">var</span> isClick = <span class="keyword">new</span> <span class="built_in">Date</span>() - <span class="built_in">this</span>.startDate &lt; <span class="number">500</span> ? <span class="literal">true</span> : <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 获取鼠标抬起时 鼠标所在单元格的坐标点</span></span><br><span class="line">	<span class="keyword">var</span> endCell = event.target.cellIndex</span><br><span class="line">	<span class="keyword">var</span> endRow = event.target.parentNode.rowIndex</span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (!isClick) &#123;</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="built_in">Math</span>.min(endRow, <span class="built_in">this</span>.startRow); i &lt;= <span class="built_in">Math</span>.max(endRow, <span class="built_in">this</span>.startRow); i++) &#123;</span><br><span class="line">			<span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="built_in">Math</span>.min(endCell, <span class="built_in">this</span>.startCell); j &lt;= <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell); j++) &#123;</span><br><span class="line">				<span class="comment">// 以获取对角坐标 填充选中的区域  只能针对结构未改变的table</span></span><br><span class="line">				<span class="comment">//this.rows[i].cells[j].className = &#x27;ui-selected&#x27;</span></span><br><span class="line"></span><br><span class="line">				<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i].cells[j]) &#123;</span><br><span class="line">					<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i].cells[j].rowSpan &gt; <span class="number">1</span>) &#123;</span><br><span class="line">						<span class="keyword">if</span> (j == <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell)) &#123;</span><br><span class="line">							<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">1</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">								<span class="keyword">if</span>(<span class="built_in">this</span>.rows[i + a].cells[j])&#123;</span><br><span class="line">									<span class="built_in">this</span>.rows[i + a].cells[j].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">								&#125;</span><br><span class="line">							&#125;</span><br><span class="line">						&#125;<span class="keyword">else</span> <span class="keyword">if</span>((j + table.rows[i].cells[j].colSpan - <span class="number">1</span> )== <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell))&#123;</span><br><span class="line">							<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">1</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">								<span class="keyword">for</span> (<span class="keyword">let</span> b = <span class="number">0</span>; b &lt; <span class="built_in">this</span>.rows[i].cells[j].colSpan; b++) &#123;</span><br><span class="line">									<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i + a].cells[j+b]) &#123;</span><br><span class="line">										<span class="built_in">this</span>.rows[i + a].cells[j+b].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">									&#125;</span><br><span class="line">								&#125;</span><br><span class="line">							&#125;</span><br><span class="line">						&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">							 <span class="keyword">var</span> maxJ = <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell)</span><br><span class="line">							<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">0</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">								<span class="keyword">if</span> (table.rows[i + a].cells[maxJ]) &#123;</span><br><span class="line">									<span class="built_in">this</span>.rows[i + a].cells[maxJ].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">								&#125;</span><br><span class="line">							&#125; </span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line"></span><br><span class="line">					<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i].cells[j].colSpan &gt; <span class="number">1</span>) &#123;</span><br><span class="line">						<span class="keyword">if</span> (j !== endCell &amp;&amp; j !== <span class="built_in">this</span>.startCell) &#123;</span><br><span class="line">							<span class="keyword">for</span> (<span class="keyword">let</span> b = <span class="number">1</span>; b &lt; <span class="built_in">this</span>.rows[i].cells[j].colSpan; b++) &#123;</span><br><span class="line">								<span class="keyword">if</span>(<span class="built_in">this</span>.rows[i].cells[j + b])&#123;</span><br><span class="line">									<span class="built_in">this</span>.rows[i].cells[j + b].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">								&#125;			</span><br><span class="line">							&#125;</span><br><span class="line">						&#125;<span class="keyword">else</span> <span class="keyword">if</span>((j + table.rows[i].cells[j].colSpan - <span class="number">1</span> )== <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell))&#123;</span><br><span class="line">							<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">0</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">								<span class="keyword">for</span> (<span class="keyword">let</span> b = <span class="number">1</span>; b &lt; <span class="built_in">this</span>.rows[i].cells[j].colSpan; b++) &#123;</span><br><span class="line">									<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i + a].cells[j+b]) &#123;</span><br><span class="line">										<span class="built_in">this</span>.rows[i + a].cells[j+b].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">									&#125;</span><br><span class="line">								&#125;</span><br><span class="line">							&#125;	</span><br><span class="line">						&#125; </span><br><span class="line">						<span class="keyword">else</span> &#123;</span><br><span class="line">							<span class="built_in">this</span>.rows[i].cells[j].className = <span class="string">&#x27;&#x27;</span></span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="built_in">this</span>.rows[i].cells[j].className += <span class="string">&#x27;ui-selected&#x27;</span></span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">// 在table中增加两个属性 获取到跨的行和列 供合并单元格</span></span><br><span class="line">		<span class="built_in">this</span>.rowspan = <span class="built_in">Math</span>.abs(endRow - <span class="built_in">this</span>.startRow) + <span class="number">1</span></span><br><span class="line">		<span class="built_in">this</span>.colspan = <span class="built_in">Math</span>.abs(endCell - <span class="built_in">this</span>.startCell) + <span class="number">1</span></span><br><span class="line"></span><br><span class="line">	&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="comment">// 清空样式</span></span><br><span class="line">		<span class="built_in">this</span>.rowspan = endRow</span><br><span class="line">		<span class="built_in">this</span>.colspan = endCell</span><br><span class="line">		<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; table.rows.length; i++) &#123;</span><br><span class="line">			<span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="number">0</span>; j &lt; table.rows[i].cells.length; j++) &#123;</span><br><span class="line">				<span class="built_in">this</span>.rows[i].cells[j].className = <span class="string">&#x27;&#x27;</span></span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="鼠标进入离开显示添加行列"><a href="#鼠标进入离开显示添加行列" class="headerlink" title="鼠标进入离开显示添加行列"></a>鼠标进入离开显示添加行列</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">   <span class="comment">/**</span></span><br><span class="line"><span class="comment">    * offset值好像是按照鼠标离每个td的位置不是离tr的位置</span></span><br><span class="line"><span class="comment">    * 所以需要利用client来处理下距离的判断</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">   <span class="built_in">this</span>.table.onmouseleave = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">		addCellBtn.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">		addRowBtn.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">	&#125;, <span class="number">3000</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">this</span>.table.onmousemove = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (event.clientX - <span class="built_in">this</span>.offsetLeft &gt;= <span class="number">8</span> &amp;&amp; event.clientX - <span class="built_in">this</span>.offsetLeft &lt;= <span class="number">20</span>) &#123;</span><br><span class="line">		<span class="built_in">this</span>.style.cursor = <span class="string">&quot;url(&#x27;img/right.png&#x27;) , auto&quot;</span></span><br><span class="line">		<span class="built_in">this</span>.colspan = <span class="built_in">this</span>.rows.length</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (event.clientY - <span class="built_in">this</span>.offsetTop &gt;= <span class="number">52</span> &amp;&amp; event.clientY - <span class="built_in">this</span>.offsetTop &lt;= <span class="number">60</span>) &#123;</span><br><span class="line">		<span class="built_in">this</span>.style.cursor = <span class="string">&quot;url(&#x27;img/down.png&#x27;) , auto&quot;</span></span><br><span class="line">	&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="built_in">this</span>.style.cursor = <span class="string">&#x27;auto&#x27;</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="鼠标点击选中一行一列事件"><a href="#鼠标点击选中一行一列事件" class="headerlink" title="鼠标点击选中一行一列事件"></a>鼠标点击选中一行一列事件</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * 判断鼠标的指针状态然后执行点击事件 选中一行/列</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line">   <span class="built_in">this</span>.table.onclick = <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (<span class="built_in">this</span>.style.cursor !== <span class="string">&#x27;auto&#x27;</span>) &#123;</span><br><span class="line">			<span class="keyword">if</span> (<span class="built_in">this</span>.style.cursor.includes(<span class="string">&#x27;down&#x27;</span>)) &#123;</span><br><span class="line">				<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">this</span>.rows.length; i++) &#123;</span><br><span class="line">					<span class="built_in">this</span>.rows[i].cells[e.target.cellIndex].className = <span class="string">&#x27;ui-selected&#x27;</span></span><br><span class="line">				&#125;</span><br><span class="line">				<span class="built_in">this</span>.rowspan = <span class="built_in">this</span>.rows.length</span><br><span class="line">			&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">this</span>.rows[e.target.parentNode.rowIndex].cells.length; i++) &#123;</span><br><span class="line">					<span class="built_in">this</span>.rows[e.target.parentNode.rowIndex].cells[i].className = <span class="string">&#x27;ui-selected&#x27;</span></span><br><span class="line">				&#125;</span><br><span class="line">				<span class="built_in">this</span>.colspan = <span class="built_in">this</span>.rows[e.target.parentNode.rowIndex].cells.length</span><br><span class="line">				<span class="built_in">this</span>.rowspan = <span class="number">1</span></span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> <span class="built_in">this</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="JavaScript封装成类的完整代码"><a href="#JavaScript封装成类的完整代码" class="headerlink" title="JavaScript封装成类的完整代码"></a>JavaScript封装成类的完整代码</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br></pre></td><td class="code"><pre><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params">win</span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> win_ = win;</span><br><span class="line">	<span class="keyword">var</span> kclass = <span class="function"><span class="keyword">function</span> (<span class="params">tableId</span>) </span>&#123;</span><br><span class="line">		<span class="built_in">this</span>._init.call(<span class="built_in">this</span>, <span class="built_in">arguments</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	kclass.fn = &#123;</span><br><span class="line"></span><br><span class="line">		tableId: <span class="string">&quot;table&quot;</span>,</span><br><span class="line">		table: <span class="literal">null</span>,</span><br><span class="line">		delTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="built_in">this</span>.table.remove()</span><br><span class="line">		&#125;,</span><br><span class="line">		addCell: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; table.rows.length; i++) &#123;</span><br><span class="line">				<span class="keyword">var</span> newCell = table.rows[i].insertCell(<span class="built_in">this</span>.table.colspan)</span><br><span class="line">				newCell.innerHTML = <span class="string">&#x27;new add&#x27;</span></span><br><span class="line">				<span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="number">0</span>; j &lt; table.rows[i].cells.length; j++) &#123;</span><br><span class="line">					<span class="built_in">this</span>.table.rows[i].cells[j].style.width = <span class="number">900</span> / <span class="built_in">this</span>.table.rows[<span class="number">0</span>].cells.length + <span class="number">1</span> + <span class="string">&#x27;px&#x27;</span></span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;,</span><br><span class="line">		addRow: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> newRow = <span class="built_in">this</span>.table.insertRow(<span class="built_in">this</span>.table.rowspan)</span><br><span class="line">			newRow.innerHTML = <span class="built_in">this</span>.table.rows[<span class="number">0</span>].innerHTML <span class="comment">//document.getSelection().getRangeAt(0).startContainer.parentNode.innerHTML</span></span><br><span class="line">		&#125;,</span><br><span class="line">		mergeTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> $t = $(<span class="string">&quot;#&quot;</span> + <span class="built_in">this</span>.tableId);</span><br><span class="line">			<span class="keyword">if</span> ($(<span class="string">&quot;table&quot;</span>, $t).length &gt; <span class="number">0</span>) &#123;</span><br><span class="line">				alert(<span class="string">&quot;不支持嵌套表格！&quot;</span>);</span><br><span class="line">				<span class="keyword">return</span>;</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			<span class="keyword">var</span> sigDel = <span class="string">&quot;sign4delete&quot;</span>; <span class="comment">// 删除标记，用作类名</span></span><br><span class="line">			<span class="keyword">var</span> sigSel = <span class="string">&quot;ui-selected&quot;</span>; <span class="comment">// 选中标记，用作类名</span></span><br><span class="line"></span><br><span class="line">			<span class="comment">// 补充单元格以便后继正确计算坐标</span></span><br><span class="line">			$(<span class="string">&quot;th,td&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="comment">// 坐标要实时计算，因会实时补充</span></span><br><span class="line">				<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">				<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line"></span><br><span class="line">				<span class="keyword">var</span> rowspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;rowspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">				<span class="keyword">var</span> colspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;colspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">				<span class="keyword">var</span> isSel = $(<span class="built_in">this</span>).hasClass(sigSel);</span><br><span class="line">				<span class="comment">// 非选单元格拆出的单元格要加删除标记</span></span><br><span class="line">				<span class="keyword">if</span> (rowspan &lt;= <span class="number">1</span> &amp;&amp; colspan &lt;= <span class="number">1</span>)</span><br><span class="line">					<span class="keyword">return</span>;</span><br><span class="line">				<span class="comment">// 跨格开插</span></span><br><span class="line">				$(<span class="string">&quot;tr&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">					<span class="keyword">var</span> idx = $(<span class="string">&quot;tr&quot;</span>, $t).index(<span class="built_in">this</span>);</span><br><span class="line">					<span class="keyword">var</span> arr, $td = $(<span class="string">&quot;&lt;td&gt;&quot;</span>).addClass(isSel ? sigSel : sigDel);</span><br><span class="line"></span><br><span class="line">					<span class="keyword">if</span> (idx == ridx) &#123;</span><br><span class="line">						<span class="comment">// 本行在 [cidx] 后插入 colspan-1 个</span></span><br><span class="line"></span><br><span class="line">						arr = $(); <span class="comment">// 准备待插单元格</span></span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; colspan - <span class="number">1</span>; i++)</span><br><span class="line">							arr = arr.add($td.clone());</span><br><span class="line">						<span class="comment">// 插入</span></span><br><span class="line">						$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).after(arr);</span><br><span class="line"></span><br><span class="line">					&#125; <span class="keyword">else</span> <span class="keyword">if</span> (ridx &lt; idx &amp;&amp; idx &lt; ridx + rowspan) &#123;</span><br><span class="line">						<span class="comment">// 以下行在 [cidx] 前插入 colspan 个</span></span><br><span class="line"></span><br><span class="line">						arr = $(); <span class="comment">// 准备待插单元格</span></span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; colspan; i++)</span><br><span class="line">							arr = arr.add($td.clone());</span><br><span class="line">						<span class="comment">// 插入</span></span><br><span class="line">						<span class="keyword">if</span> (cidx &gt; <span class="number">0</span> &amp;&amp; $(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).length &gt; <span class="number">0</span>)</span><br><span class="line">							$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).after(arr);</span><br><span class="line">						<span class="keyword">else</span> <span class="keyword">if</span> ($(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).length &gt; <span class="number">0</span>)</span><br><span class="line">							$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).before(arr);</span><br><span class="line">						<span class="keyword">else</span></span><br><span class="line">							$(<span class="built_in">this</span>).prepend(arr);</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;);</span><br><span class="line">			&#125;);</span><br><span class="line"></span><br><span class="line">			<span class="keyword">var</span> rmin = <span class="number">10000</span>,</span><br><span class="line">				cmin = <span class="number">10000</span>;</span><br><span class="line">			<span class="keyword">var</span> rmax = <span class="number">0</span>,</span><br><span class="line">				cmax = <span class="number">0</span>;</span><br><span class="line">			<span class="keyword">var</span> rnum, cnum;</span><br><span class="line">			<span class="comment">// 计算起始和跨距</span></span><br><span class="line">			$(<span class="string">&quot;th,td&quot;</span>, $t).filter(<span class="string">&quot;.&quot;</span> + sigSel).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">				rmin = ridx &lt; rmin ? ridx : rmin;</span><br><span class="line">				rmax = ridx &gt; rmax ? ridx : rmax;</span><br><span class="line">				<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line">				cmin = cidx &lt; cmin ? cidx : cmin;</span><br><span class="line">				cmax = cidx &gt; cmax ? cidx : cmax;</span><br><span class="line">			&#125;);</span><br><span class="line">			rnum = rmax - rmin + <span class="number">1</span>;</span><br><span class="line">			cnum = cmax - cmin + <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">			<span class="comment">// 合并单元格</span></span><br><span class="line">			$(<span class="string">&quot;th,td&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">				<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line">				<span class="comment">// 标记单元格待删</span></span><br><span class="line">				<span class="keyword">if</span> (rmin &lt;= ridx &amp;&amp; ridx &lt;= rmax &amp;&amp;</span><br><span class="line">					cmin &lt;= cidx &amp;&amp; cidx &lt;= cmax)</span><br><span class="line">					$(<span class="built_in">this</span>).addClass(sigDel);</span><br><span class="line">				<span class="comment">// 处理被选左上角单元格</span></span><br><span class="line">				<span class="keyword">if</span> (ridx == rmin &amp;&amp; cidx == cmin)</span><br><span class="line">					$(<span class="built_in">this</span>).removeClass(sigDel).attr(&#123;</span><br><span class="line">						rowspan: rnum,</span><br><span class="line">						colspan: cnum</span><br><span class="line">					&#125;);</span><br><span class="line">				<span class="comment">// 清理残余</span></span><br><span class="line">				<span class="keyword">if</span> ($(<span class="built_in">this</span>).attr(<span class="string">&quot;rowspan&quot;</span>) == <span class="number">1</span>) $(<span class="built_in">this</span>).removeAttr(<span class="string">&quot;rowspan&quot;</span>);</span><br><span class="line">				<span class="keyword">if</span> ($(<span class="built_in">this</span>).attr(<span class="string">&quot;colspan&quot;</span>) == <span class="number">1</span>) $(<span class="built_in">this</span>).removeAttr(<span class="string">&quot;colspan&quot;</span>);</span><br><span class="line">			&#125;).remove(<span class="string">&quot;.&quot;</span> + sigDel);</span><br><span class="line">		&#125;,</span><br><span class="line">		<span class="comment">/*</span></span><br><span class="line"><span class="comment">		mergeTable: function () &#123;</span></span><br><span class="line"><span class="comment">			var nodes = this.table.getElementsByClassName(&#x27;ui-selected&#x27;)</span></span><br><span class="line"><span class="comment">			var newNode = document.createElement(&#x27;td&#x27;)</span></span><br><span class="line"><span class="comment">			var parent = nodes[0].parentNode</span></span><br><span class="line"><span class="comment">			newNode.rowSpan = this.table.rowspan</span></span><br><span class="line"><span class="comment">			newNode.colSpan = this.table.colspan</span></span><br><span class="line"><span class="comment">			parent.replaceChild(newNode, nodes[0])</span></span><br><span class="line"><span class="comment">			while (nodes[0]) &#123;</span></span><br><span class="line"><span class="comment">				nodes[0].remove()</span></span><br><span class="line"><span class="comment">			&#125;</span></span><br><span class="line"><span class="comment">		&#125;,*/</span></span><br><span class="line">		mergeDown: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> row = <span class="built_in">document</span>.getSelection().anchorNode.parentNode.rowIndex</span><br><span class="line">			<span class="keyword">var</span> cell = <span class="built_in">document</span>.getSelection().anchorNode.cellIndex</span><br><span class="line">			<span class="keyword">var</span> node = <span class="built_in">document</span>.getSelection().anchorNode</span><br><span class="line">			<span class="keyword">if</span> (row != <span class="built_in">this</span>.table.rows.length - <span class="number">1</span> &amp;&amp; node.rowSpan == <span class="number">1</span>) &#123;</span><br><span class="line">				node.rowSpan = <span class="number">2</span></span><br><span class="line">				<span class="built_in">this</span>.table.rows[row + <span class="number">1</span>].cells[cell].remove()</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;,</span><br><span class="line">		mergeRight: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> cell = <span class="built_in">document</span>.getSelection().anchorNode.cellIndex</span><br><span class="line">			<span class="keyword">var</span> node = <span class="built_in">document</span>.getSelection().anchorNode</span><br><span class="line">			<span class="keyword">if</span> (cell != <span class="number">0</span> &amp;&amp; node.colSpan == <span class="number">1</span>) &#123;</span><br><span class="line">				node.previousElementSibling.remove()</span><br><span class="line">				node.colSpan = <span class="number">2</span></span><br><span class="line">			&#125;</span><br><span class="line">		&#125;,</span><br><span class="line">		splitTable: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> $t = $(<span class="string">&quot;#&quot;</span> + <span class="built_in">this</span>.tableId);</span><br><span class="line"></span><br><span class="line">			<span class="keyword">if</span> ($(<span class="string">&quot;table&quot;</span>, $t).length &gt; <span class="number">0</span>) &#123;</span><br><span class="line">				alert(<span class="string">&quot;不支持嵌套表格！&quot;</span>);</span><br><span class="line">				<span class="keyword">return</span>;</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			<span class="keyword">var</span> sigDel = <span class="string">&quot;sign4delete&quot;</span>; <span class="comment">// 删除标记，类名，自定义</span></span><br><span class="line">			<span class="keyword">var</span> sigSel = <span class="string">&quot;ui-selected&quot;</span>; <span class="comment">// 选中标记，类名，jQuery UI 定义</span></span><br><span class="line"></span><br><span class="line">			<span class="comment">// 补充单元格以便后继正确计算坐标</span></span><br><span class="line">			$(<span class="string">&quot;th,td&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="comment">// 坐标要实时计算，因会实时补充</span></span><br><span class="line">				<span class="keyword">var</span> ridx = $(<span class="string">&quot;tr&quot;</span>, $t).index($(<span class="built_in">this</span>).parent(<span class="string">&quot;tr&quot;</span>));</span><br><span class="line">				<span class="keyword">var</span> cidx = $(<span class="built_in">this</span>).parent().children(<span class="string">&quot;th,td&quot;</span>).index(<span class="built_in">this</span>);</span><br><span class="line">				<span class="keyword">var</span> rowspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;rowspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">				<span class="keyword">var</span> colspan = <span class="built_in">Number</span>($(<span class="built_in">this</span>).attr(<span class="string">&quot;colspan&quot;</span>)) || <span class="number">1</span>;</span><br><span class="line">				<span class="keyword">var</span> isSel = $(<span class="built_in">this</span>).hasClass(sigSel);</span><br><span class="line">				<span class="comment">// 非选单元格拆出的单元格要加删除标记</span></span><br><span class="line"></span><br><span class="line">				<span class="keyword">if</span> (rowspan &lt;= <span class="number">1</span> &amp;&amp; colspan &lt;= <span class="number">1</span>)</span><br><span class="line">					<span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">				<span class="keyword">if</span> (isSel)</span><br><span class="line">					$(<span class="built_in">this</span>).removeAttr(<span class="string">&quot;colspan&quot;</span>).removeAttr(<span class="string">&quot;rowspan&quot;</span>);</span><br><span class="line"></span><br><span class="line">				<span class="comment">// 跨格开插</span></span><br><span class="line">				$(<span class="string">&quot;tr&quot;</span>, $t).each(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">					<span class="keyword">var</span> idx = $(<span class="string">&quot;tr&quot;</span>, $t).index(<span class="built_in">this</span>);</span><br><span class="line">					<span class="keyword">var</span> arr, $td = $(<span class="string">&quot;&lt;td&gt;&quot;</span>);</span><br><span class="line"></span><br><span class="line">					<span class="keyword">if</span> (!isSel)</span><br><span class="line">						$td.addClass(sigDel);</span><br><span class="line"></span><br><span class="line">					<span class="keyword">if</span> (idx == ridx) &#123;</span><br><span class="line">						<span class="comment">// 本行在 [cidx] 后插入 colspan-1 个</span></span><br><span class="line"></span><br><span class="line">						arr = $(); <span class="comment">// 准备待插单元格</span></span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; colspan - <span class="number">1</span>; i++)</span><br><span class="line">							arr = arr.add($td.clone());</span><br><span class="line"></span><br><span class="line">						$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).after(arr);</span><br><span class="line"></span><br><span class="line">					&#125; <span class="keyword">else</span> <span class="keyword">if</span> (ridx &lt; idx &amp;&amp; idx &lt; ridx + rowspan) &#123;</span><br><span class="line">						<span class="comment">// 以下行在 [cidx] 前插入 colspan 个</span></span><br><span class="line"></span><br><span class="line">						arr = $(); <span class="comment">// 准备待插单元格</span></span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; colspan; i++)</span><br><span class="line">							arr = arr.add($td.clone());</span><br><span class="line"></span><br><span class="line">						<span class="keyword">if</span> (cidx &gt; <span class="number">0</span> &amp;&amp; $(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).length &gt; <span class="number">0</span>)</span><br><span class="line">							$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx - <span class="number">1</span>).after(arr);</span><br><span class="line">						<span class="keyword">else</span> <span class="keyword">if</span> ($(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).length &gt; <span class="number">0</span>)</span><br><span class="line">							$(<span class="string">&quot;th,td&quot;</span>, <span class="built_in">this</span>).eq(cidx).before(arr);</span><br><span class="line">						<span class="keyword">else</span></span><br><span class="line">							$(<span class="built_in">this</span>).prepend(arr);</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;);</span><br><span class="line">			&#125;);</span><br><span class="line"></span><br><span class="line">			<span class="comment">// 重新获取以取到删者并删之</span></span><br><span class="line">			$(<span class="string">&quot;th,td&quot;</span>, $t).remove(<span class="string">&quot;.&quot;</span> + sigDel);</span><br><span class="line">		&#125;,</span><br><span class="line">		<span class="comment">/*</span></span><br><span class="line"><span class="comment">		splitTable: function () &#123;</span></span><br><span class="line"><span class="comment">			var node = document.getSelection().anchorNode</span></span><br><span class="line"><span class="comment">			var td = document.createElement(&#x27;td&#x27;)</span></span><br><span class="line"><span class="comment">			if (node.rowSpan == 2 &amp;&amp; node.colSpan == 1) &#123;</span></span><br><span class="line"><span class="comment">				node.rowSpan = 1</span></span><br><span class="line"><span class="comment">				node.parentNode.nextElementSibling.appendChild(td)</span></span><br><span class="line"><span class="comment">			&#125; else if (node.colSpan == 2 &amp;&amp; node.rowSpan == 1) &#123;</span></span><br><span class="line"><span class="comment">				node.colSpan = 1</span></span><br><span class="line"><span class="comment">				node.parentNode.appendChild(td)</span></span><br><span class="line"><span class="comment">			&#125;</span></span><br><span class="line"><span class="comment">		&#125;,*/</span></span><br><span class="line">		addEvent: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="built_in">document</span>.body.onmouseup = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">		&#125;,</span><br><span class="line">		_init: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">			<span class="keyword">var</span> tableId = <span class="built_in">arguments</span>[<span class="number">0</span>][<span class="number">0</span>];</span><br><span class="line">			<span class="keyword">if</span> (!tableId)</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">&quot;table id cannot be null&quot;</span>);</span><br><span class="line">			<span class="keyword">var</span> table = <span class="built_in">document</span>.getElementById(tableId);</span><br><span class="line">			<span class="keyword">if</span> (!table || table.nodeName.toUpperCase() != <span class="string">&#x27;TABLE&#x27;</span>) &#123;</span><br><span class="line">				<span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">&quot;canot find the table,please enter the right id&quot;</span>);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">// 侧边和底部的新增按钮</span></span><br><span class="line">			<span class="keyword">var</span> addCellBtn = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;addCell&#x27;</span>)</span><br><span class="line">			<span class="keyword">var</span> addRowBtn = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;addRow&#x27;</span>)</span><br><span class="line">			<span class="built_in">this</span>.tableId = tableId;</span><br><span class="line">			<span class="built_in">this</span>.table = table;</span><br><span class="line"></span><br><span class="line">			<span class="comment">//使表格可选</span></span><br><span class="line">			<span class="built_in">this</span>.table.onmousedown = <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">				<span class="comment">// 鼠标按下的时候获取所在单元格的坐标，和鼠标按下的时间</span></span><br><span class="line">				<span class="built_in">this</span>.startRow = e.target.parentNode.rowIndex</span><br><span class="line">				<span class="built_in">this</span>.startCell = e.target.cellIndex</span><br><span class="line">				<span class="built_in">this</span>.startDate = <span class="keyword">new</span> <span class="built_in">Date</span>()</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="built_in">this</span>.table.onmouseup = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="comment">// 通过和鼠标抬起事件所获取的时间进行对比 判断是否是长按鼠标事件</span></span><br><span class="line">				<span class="keyword">var</span> isClick = <span class="keyword">new</span> <span class="built_in">Date</span>() - <span class="built_in">this</span>.startDate &lt; <span class="number">500</span> ? <span class="literal">true</span> : <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line">				<span class="comment">// 获取鼠标抬起时 鼠标所在单元格的坐标点</span></span><br><span class="line">				<span class="keyword">var</span> endCell = event.target.cellIndex</span><br><span class="line">				<span class="keyword">var</span> endRow = event.target.parentNode.rowIndex</span><br><span class="line"></span><br><span class="line">				<span class="keyword">if</span> (!isClick) &#123;</span><br><span class="line">					<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="built_in">Math</span>.min(endRow, <span class="built_in">this</span>.startRow); i &lt;= <span class="built_in">Math</span>.max(endRow, <span class="built_in">this</span>.startRow); i++) &#123;</span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="built_in">Math</span>.min(endCell, <span class="built_in">this</span>.startCell); j &lt;= <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell); j++) &#123;</span><br><span class="line">							<span class="comment">// 以获取对角坐标 填充选中的区域</span></span><br><span class="line">							<span class="comment">//this.rows[i].cells[j].className = &#x27;ui-selected&#x27;</span></span><br><span class="line"></span><br><span class="line">							<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i].cells[j]) &#123;</span><br><span class="line">								<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i].cells[j].rowSpan &gt; <span class="number">1</span>) &#123;</span><br><span class="line">									<span class="keyword">if</span> (j == <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell)) &#123;</span><br><span class="line">										<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">1</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">											<span class="keyword">if</span>(<span class="built_in">this</span>.rows[i + a].cells[j])&#123;</span><br><span class="line">												<span class="built_in">this</span>.rows[i + a].cells[j].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">											&#125;</span><br><span class="line">										&#125;</span><br><span class="line">									&#125;<span class="keyword">else</span> <span class="keyword">if</span>((j + table.rows[i].cells[j].colSpan - <span class="number">1</span> )== <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell))&#123;</span><br><span class="line">										<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">1</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">											<span class="keyword">for</span> (<span class="keyword">let</span> b = <span class="number">0</span>; b &lt; <span class="built_in">this</span>.rows[i].cells[j].colSpan; b++) &#123;</span><br><span class="line">												<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i + a].cells[j+b]) &#123;</span><br><span class="line">													<span class="built_in">this</span>.rows[i + a].cells[j+b].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">												&#125;</span><br><span class="line">											&#125;</span><br><span class="line">										&#125;</span><br><span class="line">									&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">										 <span class="keyword">var</span> maxJ = <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell)</span><br><span class="line">										<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">0</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">											<span class="keyword">if</span> (table.rows[i + a].cells[maxJ]) &#123;</span><br><span class="line">												<span class="built_in">this</span>.rows[i + a].cells[maxJ].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">											&#125;</span><br><span class="line">										&#125; </span><br><span class="line"></span><br><span class="line">									&#125;</span><br><span class="line">								&#125;</span><br><span class="line"></span><br><span class="line">								<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i].cells[j].colSpan &gt; <span class="number">1</span>) &#123;</span><br><span class="line">									<span class="keyword">if</span> (j !== endCell &amp;&amp; j !== <span class="built_in">this</span>.startCell) &#123;</span><br><span class="line">										<span class="keyword">for</span> (<span class="keyword">let</span> b = <span class="number">1</span>; b &lt; <span class="built_in">this</span>.rows[i].cells[j].colSpan; b++) &#123;</span><br><span class="line">											<span class="keyword">if</span>(<span class="built_in">this</span>.rows[i].cells[j + b])&#123;</span><br><span class="line">												<span class="built_in">this</span>.rows[i].cells[j + b].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">											&#125;			</span><br><span class="line">										&#125;</span><br><span class="line">									&#125;<span class="keyword">else</span> <span class="keyword">if</span>((j + table.rows[i].cells[j].colSpan - <span class="number">1</span> )== <span class="built_in">Math</span>.max(endCell, <span class="built_in">this</span>.startCell))&#123;</span><br><span class="line">										<span class="keyword">for</span> (<span class="keyword">let</span> a = <span class="number">0</span>; a &lt; <span class="built_in">this</span>.rows[i].cells[j].rowSpan; a++) &#123;</span><br><span class="line">											<span class="keyword">for</span> (<span class="keyword">let</span> b = <span class="number">1</span>; b &lt; <span class="built_in">this</span>.rows[i].cells[j].colSpan; b++) &#123;</span><br><span class="line">												<span class="keyword">if</span> (<span class="built_in">this</span>.rows[i + a].cells[j+b]) &#123;</span><br><span class="line">													<span class="built_in">this</span>.rows[i + a].cells[j+b].className = <span class="string">&#x27;del&#x27;</span></span><br><span class="line">												&#125;</span><br><span class="line">											&#125;</span><br><span class="line">										&#125;	</span><br><span class="line">									&#125; </span><br><span class="line">									<span class="keyword">else</span> &#123;</span><br><span class="line">										<span class="built_in">this</span>.rows[i].cells[j].className = <span class="string">&#x27;&#x27;</span></span><br><span class="line">									&#125;</span><br><span class="line">								&#125;</span><br><span class="line">								<span class="built_in">this</span>.rows[i].cells[j].className += <span class="string">&#x27;ui-selected&#x27;</span></span><br><span class="line">							&#125;</span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="comment">// 在table中增加两个属性 获取到跨的行和列 供合并单元格</span></span><br><span class="line">					<span class="built_in">this</span>.rowspan = <span class="built_in">Math</span>.abs(endRow - <span class="built_in">this</span>.startRow) + <span class="number">1</span></span><br><span class="line">					<span class="built_in">this</span>.colspan = <span class="built_in">Math</span>.abs(endCell - <span class="built_in">this</span>.startCell) + <span class="number">1</span></span><br><span class="line"></span><br><span class="line">				&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">					<span class="comment">// 清空样式</span></span><br><span class="line">					<span class="built_in">this</span>.rowspan = endRow</span><br><span class="line">					<span class="built_in">this</span>.colspan = endCell</span><br><span class="line">					<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; table.rows.length; i++) &#123;</span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="number">0</span>; j &lt; table.rows[i].cells.length; j++) &#123;</span><br><span class="line">							<span class="built_in">this</span>.rows[i].cells[j].className = <span class="string">&#x27;&#x27;</span></span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line"></span><br><span class="line">			<span class="built_in">this</span>.table.onmouseenter = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				addCellBtn.style.display = <span class="string">&#x27;inline-block&#x27;</span></span><br><span class="line">				addRowBtn.style.display = <span class="string">&#x27;block&#x27;</span></span><br><span class="line">			&#125;</span><br><span class="line">			<span class="built_in">this</span>.table.onmouseleave = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">					addCellBtn.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">					addRowBtn.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">				&#125;, <span class="number">3000</span>);</span><br><span class="line"></span><br><span class="line">			&#125;</span><br><span class="line">			<span class="built_in">this</span>.table.onmousemove = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">				<span class="keyword">if</span> (event.clientX - <span class="built_in">this</span>.offsetLeft &gt;= <span class="number">8</span> &amp;&amp; event.clientX - <span class="built_in">this</span>.offsetLeft &lt;= <span class="number">20</span>) &#123;</span><br><span class="line">					<span class="built_in">this</span>.style.cursor = <span class="string">&quot;url(&#x27;img/right.png&#x27;) , auto&quot;</span></span><br><span class="line">					<span class="built_in">this</span>.colspan = <span class="built_in">this</span>.rows.length</span><br><span class="line">				&#125; <span class="keyword">else</span> <span class="keyword">if</span> (event.clientY - <span class="built_in">this</span>.offsetTop &gt;= <span class="number">52</span> &amp;&amp; event.clientY - <span class="built_in">this</span>.offsetTop &lt;= <span class="number">60</span>) &#123;</span><br><span class="line">					<span class="built_in">this</span>.style.cursor = <span class="string">&quot;url(&#x27;img/down.png&#x27;) , auto&quot;</span></span><br><span class="line">				&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">					<span class="built_in">this</span>.style.cursor = <span class="string">&#x27;auto&#x27;</span></span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="built_in">this</span>.table.onclick = <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">				<span class="keyword">if</span> (<span class="built_in">this</span>.style.cursor !== <span class="string">&#x27;auto&#x27;</span>) &#123;</span><br><span class="line">					<span class="keyword">if</span> (<span class="built_in">this</span>.style.cursor.includes(<span class="string">&#x27;down&#x27;</span>)) &#123;</span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">this</span>.rows.length; i++) &#123;</span><br><span class="line">							<span class="built_in">this</span>.rows[i].cells[e.target.cellIndex].className = <span class="string">&#x27;ui-selected&#x27;</span></span><br><span class="line">						&#125;</span><br><span class="line">						<span class="built_in">this</span>.rowspan = <span class="built_in">this</span>.rows.length</span><br><span class="line">					&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">						<span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">this</span>.rows[e.target.parentNode.rowIndex].cells.length; i++) &#123;</span><br><span class="line">							<span class="built_in">this</span>.rows[e.target.parentNode.rowIndex].cells[i].className = <span class="string">&#x27;ui-selected&#x27;</span></span><br><span class="line">						&#125;</span><br><span class="line">						<span class="built_in">this</span>.colspan = <span class="built_in">this</span>.rows[e.target.parentNode.rowIndex].cells.length</span><br><span class="line">						<span class="built_in">this</span>.rowspan = <span class="number">1</span></span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">return</span> <span class="built_in">this</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	kclass.prototype = kclass.fn;</span><br><span class="line">	win_.ytable = (win_.ytable || kclass);</span><br><span class="line">&#125;)(<span class="built_in">window</span>);</span><br><span class="line"></span><br></pre></td></tr></table></figure>

 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-简单实现富文本"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/02/03/%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E5%AF%8C%E6%96%87%E6%9C%AC/"
    >JavaScript实现简单文本编辑器</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/02/03/%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E5%AF%8C%E6%96%87%E6%9C%AC/" class="article-date">
  <time datetime="2020-02-02T16:00:00.000Z" itemprop="datePublished">2020-02-03</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/JavaScript/">JavaScript</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h3 id="百度富文本编辑器的文件结构"><a href="#百度富文本编辑器的文件结构" class="headerlink" title="百度富文本编辑器的文件结构"></a>百度富文本编辑器的文件结构</h3><img src='/images/ueditor.png'>

<blockquote>
<p>核心属性 / 方法 / 接口</p>
</blockquote>
<h3 id="contentEditable"><a href="#contentEditable" class="headerlink" title="contentEditable"></a><a target="_blank" rel="noopener" href="https://www.runoob.com/jsref/prop-html-contenteditable.html">contentEditable</a></h3><blockquote>
<p>html属性 用来设置 或 返回元素的内容是否可以被编辑  </p>
</blockquote>
<p>语法：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">p</span> <span class="attr">contentEditable</span> = <span class="string">&#x27;true | false&#x27;</span> &gt;</span>...<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript">    HTMLElementObject.contentEditable  = <span class="literal">true</span> | <span class="literal">false</span> </span></span><br><span class="line"><span class="javascript">    HTMLElementObject.isContentEditable()  <span class="comment">// 获取元素是否是可编辑状态</span></span></span><br><span class="line"><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="document-execCommand"><a href="#document-execCommand" class="headerlink" title="document.execCommand()"></a><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand">document.execCommand()</a></h3><blockquote>
<p>操作可编辑元素的语法糖  大多数文本编辑命令都可执行</p>
</blockquote>
<p>语法：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">bool = <span class="built_in">document</span>.execCommand( aCommandName,ashowDefaultUI,aValueArgument )</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * aCommandName : 命令的名称，可用命令参考mdn</span></span><br><span class="line"><span class="comment"> * aShowDefaultUI : 是否展示用户界面  | false</span></span><br><span class="line"><span class="comment"> * aValueArgument : 一些命令需要的额外参数如字体颜色/大小  | null</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>


<h3 id="借用语法糖实现的编辑器"><a href="#借用语法糖实现的编辑器" class="headerlink" title="借用语法糖实现的编辑器"></a>借用语法糖实现的编辑器</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&#x27;bold&#x27;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>B<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;italic&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>I<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;fontSize&quot;</span> <span class="attr">data-value</span>=<span class="string">&quot;7&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>fontSize<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;foreColor&quot;</span> <span class="attr">data-value</span>=<span class="string">&quot;red&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>color<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;justifyCenter&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>居中对齐<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;justifyLeft&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>左对齐<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;justifyRight&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(this.dataset)&quot;</span>&gt;</span>右对齐<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">contentEditable</span>=<span class="string">&#x27;true&#x27;</span>&gt;</span>犹豫就会败北<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">contentEditable</span>=<span class="string">&#x27;true&#x27;</span>&gt;</span>果断就会白给<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript">        <span class="function"><span class="keyword">function</span> <span class="title">changeStyle</span>(<span class="params">data</span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> attr = data.command</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> value = data.value</span></span><br><span class="line"><span class="javascript">            value ? <span class="built_in">document</span>.execCommand(attr, <span class="literal">false</span>, value) : <span class="built_in">document</span>.execCommand(attr, <span class="literal">false</span>, <span class="literal">null</span>)</span></span><br><span class="line">        &#125;  </span><br><span class="line">    <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span> </span><br></pre></td></tr></table></figure>

<h3 id="Selection"><a href="#Selection" class="headerlink" title="Selection"></a><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Selection">Selection</a></h3><blockquote>
<p>Selection对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区，可能横跨多个元素。  </p>
</blockquote>
<p>语法：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> selObj = <span class="built_in">document</span>.getSelection()  <span class="comment">// window | document 获取Selection对象</span></span><br><span class="line"><span class="keyword">var</span> selStr = selObj.toString() <span class="comment">// 获取选中区域的 ‘纯文本’</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">document</span>.onselectionchange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;  <span class="comment">// 监听鼠标锚点的变化</span></span><br><span class="line">    <span class="built_in">console</span>.log( <span class="built_in">document</span>.getSelection() )</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Selection = &#123;</span></span><br><span class="line"><span class="comment">     *  anchorNode: node 选取起点所在节点，</span></span><br><span class="line"><span class="comment">     *  anchorOffset: num 起点偏移量,</span></span><br><span class="line"><span class="comment">     *  focusNode: node 选取终点所在节点,</span></span><br><span class="line"><span class="comment">     *  focusOffset: num 终点偏移量,</span></span><br><span class="line"><span class="comment">     *  isCollapsed: bool 起始点是否在同一位置,</span></span><br><span class="line"><span class="comment">     *  rangeCount: 返回该选区所包含的连续范围的数量</span></span><br><span class="line"><span class="comment">     * </span></span><br><span class="line"><span class="comment">     * &#125;</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h3 id="Range"><a href="#Range" class="headerlink" title="Range"></a><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Range">Range</a></h3><blockquote>
<p>表示一个包含节点与文本节点的一部分的文档片段  </p>
</blockquote>
<p>语法: </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个文档范围</span></span><br><span class="line"><span class="keyword">var</span> range = <span class="built_in">document</span>.createRange()</span><br><span class="line"><span class="keyword">var</span> range = <span class="keyword">new</span> Range()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取选中的文档范围</span></span><br><span class="line"><span class="keyword">var</span> range = <span class="built_in">document</span>.getSelection().getRangeAt(<span class="number">0</span>)  </span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Range = &#123;</span></span><br><span class="line"><span class="comment"> *  collapsed : 起始点位置是否相同,</span></span><br><span class="line"><span class="comment"> *  commonAncetorContainer : 选中区域所在的完整节点,  eg: &lt;b&gt; hhh&lt;i&gt;5[5&lt;/i&gt;6]6&lt;/b&gt; -&gt; &lt;b&gt; hhh&lt;i&gt;55&lt;/i&gt;66&lt;/b&gt;</span></span><br><span class="line"><span class="comment"> *  endContainer : 包含range的终点节点,  -&gt; 66</span></span><br><span class="line"><span class="comment"> *  endOffset : 返回一个表示 Range 终点在 endContainer 中的位置的数字。 -&gt; 1 （选中的6在66中排位第几）</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * Range.cloneContents()    返回一个包含 Range 中所有节点的文档片段</span></span><br><span class="line"><span class="comment"> * Range.deleteContents()    移除range包含的内容</span></span><br><span class="line"><span class="comment"> * Range.extractContents()    把 Range 的内容从文档树移动到一个文档片段中</span></span><br><span class="line"><span class="comment"> * Range.insertNode(Node)    在range起点处插入一个节点</span></span><br><span class="line"><span class="comment"> * Range.surroundContents(newNode)     将range内容移动到一个新的节点中</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<h3 id="利用-range-amp-selection-接口实现的简易编辑器"><a href="#利用-range-amp-selection-接口实现的简易编辑器" class="headerlink" title="利用 range &amp; selection 接口实现的简易编辑器"></a>利用 range &amp; selection 接口实现的简易编辑器</h3><blockquote>
<p>有bug  </p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;b&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(dataset)&quot;</span>&gt;</span> B <span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;i&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(dataset)&quot;</span>&gt;</span> I <span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-command</span>=<span class="string">&quot;h1&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(dataset)&quot;</span>&gt;</span> h1 <span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-value</span>=<span class="string">&quot;textAlign:center&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(dataset)&quot;</span>&gt;</span> 居中<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-value</span>=<span class="string">&quot;textAlign:right&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(dataset)&quot;</span>&gt;</span> 居右<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">data-value</span>=<span class="string">&quot;textAlign:left&quot;</span> <span class="attr">onclick</span>=<span class="string">&quot;changeStyle(dataset)&quot;</span>&gt;</span> 居左<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> <span class="attr">id</span>=<span class="string">&#x27;btn&#x27;</span>&gt;</span></span><br><span class="line">        测试按钮</span><br><span class="line">    <span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">contentEditable</span>=<span class="string">&#x27;true&#x27;</span>&gt;</span>犹豫<span class="tag">&lt;<span class="name">b</span>&gt;</span>就会败北<span class="tag">&lt;<span class="name">i</span>&gt;</span>52<span class="tag">&lt;/<span class="name">i</span>&gt;</span>墨菲<span class="tag">&lt;/<span class="name">b</span>&gt;</span>定律<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">contentEditable</span>=<span class="string">&#x27;true&#x27;</span>&gt;</span>薛定谔的猫🐱<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript">        <span class="comment">// 1.surrounContents(Node) 在原有内容 的基础上包裹一层node节点</span></span></span><br><span class="line"><span class="javascript">        <span class="comment">// 不能判断是否已经有该元素</span></span></span><br><span class="line"><span class="javascript">        <span class="function"><span class="keyword">function</span> <span class="title">changeStyle</span>(<span class="params">data</span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> tagName = data.command || <span class="literal">null</span></span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> value = data.value || <span class="literal">null</span></span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> selobj = <span class="built_in">document</span>.getSelection()</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> Node = <span class="built_in">document</span>.createElement(tagName)</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> range = selobj.getRangeAt(<span class="number">0</span>)</span></span><br><span class="line">            if(value)&#123;</span><br><span class="line"><span class="javascript">                <span class="keyword">var</span> attr = value.split(<span class="string">&#x27;:&#x27;</span>)[<span class="number">0</span>].trim(),</span></span><br><span class="line"><span class="javascript">                 cssStyle = value.split(<span class="string">&#x27;:&#x27;</span>)[<span class="number">1</span>].trim() </span></span><br><span class="line">                 range.commonAncestorContainer.parentElement.style[attr] = cssStyle</span><br><span class="line"><span class="javascript">            &#125;<span class="keyword">else</span>&#123;</span></span><br><span class="line">                range.surroundContents(Node)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"><span class="javascript">        <span class="comment">// 2.把选择的范围节点删除 在字符串外重新添加标签，只能一种标签存在</span></span></span><br><span class="line"><span class="javascript">        btn.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> range =  <span class="built_in">document</span>.getSelection().getRangeAt(<span class="number">0</span>)</span></span><br><span class="line"><span class="javascript">            <span class="keyword">var</span> oB = <span class="built_in">document</span>.createElement(<span class="string">&#x27;b&#x27;</span>)</span></span><br><span class="line">            oB.innerHTML = range.toString()</span><br><span class="line">            range.deleteContents()</span><br><span class="line">            range.insertNode(oB)</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br></pre></td></tr></table></figure> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-一些废话"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/31/%E4%B8%80%E4%BA%9B%E5%BA%9F%E8%AF%9D/"
    >一些废话</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/31/%E4%B8%80%E4%BA%9B%E5%BA%9F%E8%AF%9D/" class="article-date">
  <time datetime="2020-01-31T02:21:42.000Z" itemprop="datePublished">2020-01-31</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E6%97%A5%E5%B8%B8/">日常</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <pre>
虽然2020才过了一个多月，但已经充分展示出他的不平凡
这还得从一只🦇说起。。。
资本家犯下的罪恶买单的还是广大群众
1.22 我从长沙回凤凰的时候湖南还没有一例
到现在 2.13 一个月还没到累积病例已经900多了
从回家到现在我就出过两次门 
本来和朋友约的电影、饭局也泡汤
现在靠我一月底买的50个口罩苟活
（虽然没有这次肺炎我放假的状态也差不太多）
但还是闹得人心惶惶的 交通也瘫痪 娱乐场所被迫关门
很多企业应该是损失惨重 人也被迫"禁足"
整天无所事事 刷微博、微信、QQ等沙雕网友的新段子

实习的公司也响应号召实施远程办公，换了一个正常的项目组长，美滋滋
因为前期没有接触过项目 现在远程也说不清楚 这两个星期基本没我什么事
就把源码看了下，给了份报告，把自己简单实现效果的源码提交过去 
组长也没找过我了 换做之前那个 没事也会专门给我找点不归我做的事情做

刚好借疫情的原因给老板说了辞职 也算是给了我一个充分的借口
但就是月底之前怎么赶回去还不清楚 说是下周一复工的 目前还没确定
昨天跟合租的说我可能下周一会回去 他可能不想我在3月之前回去（好继续分担租金？）
还骗我说我们小区感染了几个？
然后我就去看了下，周边五公里都没有被感染案例 也是醉了

现在的人为了自己的利益什么谎都能撒 什么事都敢做 脑子都不动

翻篇---------

可能是因为闲的 在B站首页看到塔罗牌测试的，进去了两个测试看了下
第一个是关于未来的
第二个是关于学业事业的
两个都说到了未来会朝着好的方向发展 （不是很信这些 但也希望能实现）

没怎么了解过塔罗牌 唯一一次是在初二同学给测过一次
说来也巧 那次也是和这次说的差不多
原话大概是 
“
    虽然之前做了很多努力 但是都没有什么收获
    但在后期 关键时候的都会朝着一个好的方向发展 有个好的运势
”
还算被预言到了
初三那年的考试排名都还靠前
高中招提前批 本来说给分到B班的
后面因为竞赛成绩比较高又给调到A班了 我都不知道我怎么考的
我当时的状态就是 我何德何能？ 后面班级比我优秀的太多了

从小到大 我一直的成绩都是中等 或者中等偏下
也不知道为什么 到初三 、 高三的时候成绩总会慢慢提上来 稳定到10几
但是我自己没有觉得我突然奋发图强 然后变强了
我一直没怎么变啊？ 我也没觉得自己学会了什么
自己也想过原因 可能是我比较有韧性 能一直坚持
所以会慢慢累积 然后提升
但是我自己真的没有觉得我的知识丰富了QAQ
特别是高中除了数学外的科目
我都没什么把握 分数听天由命的那种

我真的不是聪明的人 要加倍的努力才能和别人到一个水平线

刚去文科班那会儿 历史基本是30-40分 倒数行列的
我的几个同班同学都跟我说过我不适合文科
好在没有放弃 在努力之后到达了平均线、超过了平均线
可能效果不是显而易见的以至于我自己有没有感觉到变化
直到高三我才意识到，我的成绩慢慢稳定在水平线以内

现在又将面临一个人生的转折点
从一个文科生 转为一个程序员
我们的专业课 就是杂而不精 老师基本都是混子
只能靠自己自学 学的时候也感觉到了自己对于代码逻辑底层的东西真的看不进去
真的很羡慕天赋型的人 我花了很长的时间去看、学这些东西
好像没有什么用 就是记不住 理解不了 没有能交流的人 
我不知道自己还有没有足够的运气让我能朝着好的方向继续走

说到这里 我也不知道自己想要表达什么 也大概是闲的
</pre> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-方块运动"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/16/%E6%96%B9%E5%9D%97%E8%BF%90%E5%8A%A8/"
    >CSS3 立体轮播</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/16/%E6%96%B9%E5%9D%97%E8%BF%90%E5%8A%A8/" class="article-date">
  <time datetime="2020-01-16T09:16:00.000Z" itemprop="datePublished">2020-01-16</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/CSS/">CSS</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="CSS3-立体轮播"><a href="#CSS3-立体轮播" class="headerlink" title="CSS3 立体轮播"></a>CSS3 立体轮播</h2><p> 最近比较迷css，可能是JavaScript看的头疼<br> 可以用作图片轮播，换成小的立方体还可以当做是缓冲动画<br> 效果很好看 就是每次弄 旋转角度、移动位置的时候头疼<br> <del>没有找到方法</del>  就是我空间感不行</p>
<style>
    .cubeCover{
        width: 100px;
        height: 300px;
        margin-top: 150px;
        margin-left: 200px;
    }
    .cubeCover .cube{
        transform-style: preserve-3d;
        width: 100%;
        height: 100%;
        position: relative;
        transform: rotateY(20deg) rotateX(-20deg) ;
        animation: move1 6s linear infinite .75s;
    }
    .cubeCover .cube div{
        border: 1px solid #ccc;
        width: 100%;
        height: 100%;
        position: absolute;
    }
    .cubeCover .cube div:nth-child(1){
        transform:translateZ(-150px);
        background: url('/images/bottom.jpg');
        background-position: 0 0;
    }
    .cubeCover .cube div:nth-child(2){
        transform: rotateX(90deg) translateZ(150px);
        background: url('/images/side.jpg');
        background-position: 0 0;
    }
    .cubeCover .cube div:nth-child(3){
        transform:rotateX(90deg) translateZ(-150px)  ;
        background: url('/images/top.jpg');
    }
    .cubeCover .cube div:nth-child(4){
        width: 300px;
        transform: rotateY(90deg) translateZ(-150px);
        background: lightblue;
    }
    .cubeCover .cube div:nth-child(5){
        width: 300px;
        transform: rotateY(90deg) translateZ(-50px);
        background: lightblue;
    }
    .cubeCover .cube div:nth-child(6){
        transform: translateZ(150px);
        background: url('/images/avatar.jpg');
        background-position: 0 0;
    }
    .cubeCover .cube2{
        margin-top: -300px;
        margin-left: 90px;
        z-index: -1;
        animation: move1 6s linear infinite .5s;
    }
    .cubeCover .cube2 div:nth-child(1),.cubeCover .cube2 div:nth-child(2),.cubeCover .cube2 div:nth-child(3),.cubeCover .cube2 div:nth-child(6){
        background-position: -100px 0;
    }
    .cubeCover .cube3{
        margin-top: -300px;
        margin-left: 180px;
        z-index: -2;
        animation: move1 6s linear infinite .25s;
    }
    .cubeCover .cube3 div:nth-child(1),.cubeCover .cube3 div:nth-child(2),.cubeCover .cube3 div:nth-child(3),.cubeCover .cube3 div:nth-child(6){
        background-position: -200px 0;
    }
    .cubeCover .cube4{
        margin-top: -300px;
        margin-left: 270px;
        z-index: -3;
        animation: move1 6s linear infinite ;
    }
    .cubeCover .cube4 div:nth-child(1),.cubeCover .cube4 div:nth-child(2),.cubeCover .cube4 div:nth-child(3),.cubeCover .cube4 div:nth-child(6){
        background-position: -300px 0;
    }
    @keyframes move1 {
        12.5%,25%{
            transform:rotateY(20deg) rotateX(70deg);
        }
        42.5%,55%{
            transform:rotateY(20deg) rotateX(160deg);
        }
        62.5%,75%{
            transform:rotateY(20deg) rotateX(250deg);
        }
        92.5%,100%{
            transform:rotateY(20deg) rotateX(340deg);
        }
    }
</style>
<div class="cubeCover">
    <div class="cube">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
    <div class="cube cube2">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
    <div class="cube cube3">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
    <div class="cube cube4">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
</div>
<br>
<br>
<br>
<br>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span>&#123;</span></span><br><span class="line">        width: 100px;</span><br><span class="line">        height: 300px;</span><br><span class="line">        margin-top: 150px;</span><br><span class="line">        margin-left: 200px;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span>&#123;</span></span><br><span class="line">        transform-style: preserve-3d;</span><br><span class="line">        width: 100%;</span><br><span class="line">        height: 100%;</span><br><span class="line">        position: relative;</span><br><span class="line">        transform: rotateY(20deg) rotateX(-20deg) ;</span><br><span class="line"><span class="css">        <span class="selector-tag">animation</span>: <span class="selector-tag">move1</span> 6<span class="selector-tag">s</span> <span class="selector-tag">linear</span> <span class="selector-tag">infinite</span> <span class="selector-class">.75s</span>;</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span>&#123;</span></span><br><span class="line"><span class="css">        <span class="selector-tag">border</span>: 1<span class="selector-tag">px</span> <span class="selector-tag">solid</span> <span class="selector-id">#ccc</span>;</span></span><br><span class="line">        width: 100%;</span><br><span class="line">        height: 100%;</span><br><span class="line">        position: absolute;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(1)</span>&#123;</span></span><br><span class="line"><span class="css">        <span class="selector-tag">transform</span><span class="selector-pseudo">:translateZ(-150px)</span>;</span></span><br><span class="line">        background: url(&#x27;/images/bottom.jpg&#x27;);</span><br><span class="line">        background-position: 0 0;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(2)</span>&#123;</span></span><br><span class="line">        transform: rotateX(90deg) translateZ(150px);</span><br><span class="line">        background: url(&#x27;/images/side.jpg&#x27;);</span><br><span class="line">        background-position: 0 0;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(3)</span>&#123;</span></span><br><span class="line"><span class="css">        <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateX(90deg)</span> <span class="selector-tag">translateZ</span>(<span class="selector-tag">-150px</span>)  ;</span></span><br><span class="line">        background: url(&#x27;/images/top.jpg&#x27;);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(4)</span>&#123;</span></span><br><span class="line">        width: 300px;</span><br><span class="line">        transform: rotateY(90deg) translateZ(-150px);</span><br><span class="line">        background: lightblue;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(5)</span>&#123;</span></span><br><span class="line">        width: 300px;</span><br><span class="line">        transform: rotateY(90deg) translateZ(-50px);</span><br><span class="line">        background: lightblue;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(6)</span>&#123;</span></span><br><span class="line">        transform: translateZ(150px);</span><br><span class="line">        background: url(&#x27;/images/avatar.jpg&#x27;);</span><br><span class="line">        background-position: 0 0;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube2</span>&#123;</span></span><br><span class="line">        margin-top: -300px;</span><br><span class="line">        margin-left: 90px;</span><br><span class="line">        z-index: -1;</span><br><span class="line"><span class="css">        <span class="selector-tag">animation</span>: <span class="selector-tag">move1</span> 6<span class="selector-tag">s</span> <span class="selector-tag">linear</span> <span class="selector-tag">infinite</span> <span class="selector-class">.5s</span>;</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube2</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(1)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube2</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(2)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube2</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(3)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube2</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(6)</span>&#123;</span></span><br><span class="line">        background-position: -100px 0;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube3</span>&#123;</span></span><br><span class="line">        margin-top: -300px;</span><br><span class="line">        margin-left: 180px;</span><br><span class="line">        z-index: -2;</span><br><span class="line"><span class="css">        <span class="selector-tag">animation</span>: <span class="selector-tag">move1</span> 6<span class="selector-tag">s</span> <span class="selector-tag">linear</span> <span class="selector-tag">infinite</span> <span class="selector-class">.25s</span>;</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube3</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(1)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube3</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(2)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube3</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(3)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube3</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(6)</span>&#123;</span></span><br><span class="line">        background-position: -200px 0;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube4</span>&#123;</span></span><br><span class="line">        margin-top: -300px;</span><br><span class="line">        margin-left: 270px;</span><br><span class="line">        z-index: -3;</span><br><span class="line">        animation: move1 6s linear infinite ;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.cubeCover</span> <span class="selector-class">.cube4</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(1)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube4</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(2)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube4</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(3)</span>,<span class="selector-class">.cubeCover</span> <span class="selector-class">.cube4</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(6)</span>&#123;</span></span><br><span class="line">        background-position: -300px 0;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="keyword">@keyframes</span> move1 &#123;</span></span><br><span class="line"><span class="css">        12<span class="selector-class">.5</span>%,25%&#123;</span></span><br><span class="line"><span class="css">            <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateY(20deg)</span> <span class="selector-tag">rotateX</span>(70<span class="selector-tag">deg</span>);</span></span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        42<span class="selector-class">.5</span>%,55%&#123;</span></span><br><span class="line"><span class="css">            <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateY(20deg)</span> <span class="selector-tag">rotateX</span>(160<span class="selector-tag">deg</span>);</span></span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        62<span class="selector-class">.5</span>%,75%&#123;</span></span><br><span class="line"><span class="css">            <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateY(20deg)</span> <span class="selector-tag">rotateX</span>(250<span class="selector-tag">deg</span>);</span></span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        92<span class="selector-class">.5</span>%,100%&#123;</span></span><br><span class="line"><span class="css">            <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateY(20deg)</span> <span class="selector-tag">rotateX</span>(340<span class="selector-tag">deg</span>);</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cubeCover&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cube&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cube cube2&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cube cube3&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cube cube4&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-命令模式"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/16/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F/"
    >【第九章】 命令模式</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/16/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F/" class="article-date">
  <time datetime="2020-01-16T07:16:00.000Z" itemprop="datePublished">2020-01-16</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="命令模式的用途"><a href="#命令模式的用途" class="headerlink" title="命令模式的用途"></a>命令模式的用途</h2><blockquote>
<p>一个执行某些特定事情的指令<br>常见的应用场景 : 有时候需要向某些对象发送请求，但并不知道请求的接受者是谁，也不知道被请求的操作是什么。此时希望用一种耦合的方式来设计程序，使得请求发送者和请求接受者能够消除彼此之间的耦合关系  </p>
</blockquote>
<h2 id="命令模式实例"><a href="#命令模式实例" class="headerlink" title="命令模式实例"></a>命令模式实例</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 请求发送者 和 请求接受者 解耦开</span></span><br><span class="line"><span class="keyword">var</span> oBtn1 = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;btn1&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> oBtn2 = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;btn2&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> oBtn3 = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;btn3&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 执行命令的函数 </span></span><br><span class="line"><span class="keyword">var</span> setCommand = <span class="function"><span class="keyword">function</span> (<span class="params">button, command</span>) </span>&#123;</span><br><span class="line">    button.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        command.execute();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 提供的功能菜单</span></span><br><span class="line"><span class="keyword">var</span> MenuBar = &#123;</span><br><span class="line">    refresh: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;刷新菜单目录&#x27;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> SubMenu = &#123;</span><br><span class="line">    add: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;增加子菜单&#x27;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    del: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;删除子菜单&#x27;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 封装命令类</span></span><br><span class="line"><span class="keyword">var</span> RefreshMenuBarCommand = <span class="function"><span class="keyword">function</span> (<span class="params">receiver</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.receiver = receiver</span><br><span class="line">&#125;</span><br><span class="line">RefreshMenuBarCommand.prototype.execute = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.receiver.refresh();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> AddSubMenuCommand = <span class="function"><span class="keyword">function</span> (<span class="params">receiver</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.receiver = receiver;</span><br><span class="line">&#125;</span><br><span class="line">AddSubMenuCommand.prototype.execute = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.receiver.add();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> DelSubMenuCommand = <span class="function"><span class="keyword">function</span> (<span class="params">receiver</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.receiver = receiver;</span><br><span class="line">&#125;;</span><br><span class="line">DelSubMenuCommand.prototype.execute = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.receiver.del()</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//最后就是把命令接收者传入到 command 对象中，并且把 command 对象安装到 button 上面</span></span><br><span class="line"><span class="keyword">var</span> refreshMenuBarCommand = <span class="keyword">new</span> RefreshMenuBarCommand( MenuBar );</span><br><span class="line"><span class="keyword">var</span> addSubMenuCommand = <span class="keyword">new</span> AddSubMenuCommand(SubMenu);</span><br><span class="line"><span class="keyword">var</span> delSubMenuCommand = <span class="keyword">new</span> DelSubMenuCommand(SubMenu);</span><br><span class="line">setCommand(btn1, refreshMenuBarCommand);    <span class="comment">// 刷新菜单目录</span></span><br><span class="line">setCommand(btn2, addSubMenuCommand);        <span class="comment">// 增加子菜单</span></span><br><span class="line">setCommand(btn3, delSubMenuCommand);        <span class="comment">// 删除子菜单</span></span><br></pre></td></tr></table></figure>
<h2 id="JavaScript中的命令模式"><a href="#JavaScript中的命令模式" class="headerlink" title="JavaScript中的命令模式"></a>JavaScript中的命令模式</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ...</span></span><br><span class="line"><span class="keyword">var</span> RefreshMenuBarCommand = <span class="function"><span class="keyword">function</span> (<span class="params">receiver</span>) </span>&#123;</span><br><span class="line">   <span class="keyword">return</span> &#123;</span><br><span class="line">       execute: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">           receiver.refresh()</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// ....</span></span><br><span class="line"><span class="keyword">var</span> refreshMenuBarCommand = RefreshMenuBarCommand( MenuBar ); </span><br><span class="line">setCommand( btn1, refreshMenuBarCommand ); <span class="comment">// 刷新菜单目录</span></span><br></pre></td></tr></table></figure>
<h2 id="宏命令"><a href="#宏命令" class="headerlink" title="宏命令"></a>宏命令</h2><blockquote>
<p>是一组命令的集合，通过执行宏命令的方式，可以一次执行一批命令</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//下面我们看看如何逐步创建一个宏命令。首先，我们依然要创建好各种 Command：</span></span><br><span class="line"><span class="keyword">var</span> closeDoorCommand = &#123; </span><br><span class="line"> execute: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123; </span><br><span class="line"> <span class="built_in">console</span>.log( <span class="string">&#x27;关门&#x27;</span> ); </span><br><span class="line"> &#125; </span><br><span class="line">&#125;; </span><br><span class="line"><span class="keyword">var</span> openPcCommand = &#123; </span><br><span class="line"> execute: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123; </span><br><span class="line"> <span class="built_in">console</span>.log( <span class="string">&#x27;开电脑&#x27;</span> ); </span><br><span class="line"> &#125; </span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">/*接下来定义宏命令 MacroCommand，它的结构也很简单。macroCommand.add 方法表示把子命令添加进宏命令对象，当调用宏命令对象的 execute 方法时，会迭代这一组子命令对象，并且依次执行它们的 execute 方法：*/</span></span><br><span class="line"><span class="keyword">var</span> MacroCommand = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123; </span><br><span class="line"> <span class="keyword">return</span> &#123; </span><br><span class="line">    commandsList: [], </span><br><span class="line">    add: <span class="function"><span class="keyword">function</span>(<span class="params"> command </span>)</span>&#123; </span><br><span class="line">        <span class="built_in">this</span>.commandsList.push( command ); </span><br><span class="line">    &#125;, </span><br><span class="line">    execute: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123; </span><br><span class="line">        <span class="keyword">for</span> ( <span class="keyword">var</span> i = <span class="number">0</span>, command; command = <span class="built_in">this</span>.commandsList[ i++ ]; )&#123; </span><br><span class="line">            command.execute(); </span><br><span class="line">        &#125; </span><br><span class="line">    &#125; </span><br><span class="line"> &#125; </span><br><span class="line">&#125;; </span><br><span class="line"><span class="keyword">var</span> macroCommand = MacroCommand(); </span><br><span class="line">macroCommand.add( closeDoorCommand ); </span><br><span class="line">macroCommand.add( openPcCommand ); </span><br><span class="line">macroCommand.add( openQQCommand ); </span><br><span class="line">macroCommand.execute();</span><br></pre></td></tr></table></figure>
<h2 id="智能命令与傻瓜命令"><a href="#智能命令与傻瓜命令" class="headerlink" title="智能命令与傻瓜命令"></a>智能命令与傻瓜命令</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> closeDoorCommand = &#123; </span><br><span class="line">    execute: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123; </span><br><span class="line">        <span class="built_in">console</span>.log( <span class="string">&#x27;关门&#x27;</span> ); </span><br><span class="line">    &#125; </span><br><span class="line">&#125;; </span><br></pre></td></tr></table></figure>
<p>closeDoorCommand 中没有包含任何 receiver 的信息，它本身就包揽了执行请求的行为，这跟我们之前看到的命令对象都包含了一个 receiver 是矛盾的。 一般来说，命令模式都会在 command 对象中保存一个接收者来负责真正执行客户的请求，这种情况下命令对象是<strong style='color:red'>“傻瓜式”</strong>的，它只负责把客户的请求转交给接收者来执行，这种模式的好处是请求发起者和请求接收者之间尽可能地得到了解耦。</p>
<p>但是我们也可以定义一些更“聪明”的命令对象，“聪明”的命令对象可以直接实现请求，这样一来就不再需要接收者的存在，这种“聪明”的命令对象也叫作智能命令。没有接收者的智能命令，退化到和策略模式非常相近，从代码结构上已经无法分辨它们，能分辨的只有它们意图的不同。策略模式指向的问题域更小，所有策略对象的目标总是一致的，它们只是达到这个目标的不同手段，它们的内部实现是针对“算法”而言的。而智能命令模式指向的问题域更广，command对象解决的目标更具发散性。命令模式还可以完成撤销、排队等功能。</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-clip-path"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/15/clip-path/"
    >clip-path</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/15/clip-path/" class="article-date">
  <time datetime="2020-01-15T07:16:00.000Z" itemprop="datePublished">2020-01-15</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/CSS/">CSS</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="发现了一个有意思的CSS属性"><a href="#发现了一个有意思的CSS属性" class="headerlink" title="发现了一个有意思的CSS属性"></a>发现了一个有意思的CSS属性</h2><p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/clip-path">属性详情</a><br><a target="_blank" rel="noopener" href="https://www.html.cn/tool/css-clip-path/">clip-path生成器</a></p>
<blockquote>
<p>clip-path ： 创建一个只有元素的部分区域可以显示的剪切区域</p>
</blockquote>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 我没有接触过svg 所以只写了几个我觉得能常用的属性*/</span></span><br><span class="line"><span class="selector-tag">clip-path</span>: <span class="selector-tag">circle</span>( 50% <span class="selector-tag">at</span> 50% 50%);     <span class="comment">/* 剪裁成 【圆形】 第一个参数是 圆半径 at 圆心坐标*/</span></span><br><span class="line"><span class="selector-tag">clip-path</span>: <span class="selector-tag">ellipse</span>( 50% 25% <span class="selector-tag">at</span> 50% 50%);    <span class="comment">/*剪裁成 【椭圆】 第一个参数是 横向半径 第二个是 纵向半径 at 圆心坐标  当半径一致 相当于圆*/</span></span><br><span class="line"><span class="selector-tag">clip-path</span>: <span class="selector-tag">polygon</span>( 50% 0,0 100%,100% 100%);    <span class="comment">/* 剪裁成任意形状 后跟每个点坐标  这是个三角形 注意点连接的顺序！ 如下：*/</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<img src='/images/clippath.png' width='400px'/>  

<h2 id="可以实现的效果"><a href="#可以实现的效果" class="headerlink" title="可以实现的效果"></a>可以实现的效果</h2><blockquote>
<p>我感觉比伪类方便  可以代替圆角之类的  也可以结合动画之类的</p>
</blockquote>
<style>
.clipPath{
    width:150px;
    height: 150px;
    background-image: url('/images/avatar.jpg'); 
    background-size:100% 100%;
    display:inline-block;  
}
.clipPath.dv1{
    clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
}
.clipPath.dv2{
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.clipPath.dv3{
    clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
}
.clipPath.dv4{
    /* clip-path: ellipse(100% 100% at 0% 0%); */
    clip-path: circle(100% at 0% 0%);
}
.clipPath.dv5{
  clip-path: polygon(0% 0%, 0% 100%, 25% 100%, 25% 25%, 75% 25%, 75% 75%, 25% 75%, 25% 100%, 100% 100%, 100% 0%);
}
</style>
<div class="clipPath dv1"></div>
<div class="clipPath dv2"></div>
<div class="clipPath dv3"></div>
<div class="clipPath dv4"></div>
<div class="clipPath dv5"></div>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css"><span class="selector-class">.clipPath</span>&#123;</span></span><br><span class="line"><span class="css">    <span class="selector-tag">width</span><span class="selector-pseudo">:150px</span>;</span></span><br><span class="line">    height: 150px;</span><br><span class="line">    background-image: url(&#x27;/images/avatar.jpg&#x27;); </span><br><span class="line"><span class="css">    <span class="selector-tag">background-size</span><span class="selector-pseudo">:100</span>% 100%;</span></span><br><span class="line"><span class="css">    <span class="selector-tag">display</span><span class="selector-pseudo">:inline-block</span>;  </span></span><br><span class="line">&#125;</span><br><span class="line"><span class="css"><span class="selector-class">.clipPath</span><span class="selector-class">.dv1</span>&#123;</span></span><br><span class="line">    clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);</span><br><span class="line">&#125;</span><br><span class="line"><span class="css"><span class="selector-class">.clipPath</span><span class="selector-class">.dv2</span>&#123;</span></span><br><span class="line">    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);</span><br><span class="line">&#125;</span><br><span class="line"><span class="css"><span class="selector-class">.clipPath</span><span class="selector-class">.dv3</span>&#123;</span></span><br><span class="line">    clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);</span><br><span class="line">&#125;</span><br><span class="line"><span class="css"><span class="selector-class">.clipPath</span><span class="selector-class">.dv4</span>&#123;</span></span><br><span class="line"><span class="css">    <span class="comment">/* clip-path: ellipse(100% 100% at 0% 0%); 效果一致*/</span></span></span><br><span class="line">    clip-path: circle(100% at 0% 0%);</span><br><span class="line">&#125;</span><br><span class="line"><span class="css"><span class="selector-class">.clipPath</span><span class="selector-class">.dv5</span>&#123;</span></span><br><span class="line">  clip-path: polygon(0% 0%, 0% 100%, 25% 100%, 25% 25%, 75% 25%, 75% 75%, 25% 75%, 25% 100%, 100% 100%, 100% 0%);</span><br><span class="line">&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;clipPath dv1&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;clipPath dv2&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;clipPath dv3&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;clipPath dv4&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;clipPath dv5&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-发布订阅者模式"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/14/%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E8%80%85%E6%A8%A1%E5%BC%8F/"
    >【第八章】 发布-订阅模式</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/14/%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E8%80%85%E6%A8%A1%E5%BC%8F/" class="article-date">
  <time datetime="2020-01-14T10:16:00.000Z" itemprop="datePublished">2020-01-14</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>优点： </p>
<ol>
<li>时间上的解耦</li>
<li>对象之间的解耦</li>
</ol>
</blockquote>
<blockquote>
<p>缺点:   消耗时间和内存</p>
</blockquote>
<h2 id="自定义事件"><a href="#自定义事件" class="headerlink" title="自定义事件"></a>自定义事件</h2><blockquote>
<p>如何实现发布-订阅模式:</p>
<ol>
<li>指定发布者</li>
<li>给发布者添加一个缓存列表，用于存放回调函数 以便通知 订阅者</li>
<li>发布消息的时候，发布者会遍历这个缓存列表，依次触发存放的订阅者回调函数<br>(还可以在回调函数中填入一些参数，订阅者可以接收这些参数。eg：售楼处可以在给订阅者短信内加上房子的单价、面积等信息)</li>
</ol>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> salesOffices = &#123;&#125;   <span class="comment">// 售楼处</span></span><br><span class="line">salesOffices.clientList = []    <span class="comment">// 缓存列表，存放订阅者的回调函数</span></span><br><span class="line">salesOffices.listen = <span class="function"><span class="keyword">function</span>(<span class="params">fn</span>)</span>&#123;     <span class="comment">// 增加订阅者</span></span><br><span class="line">    <span class="built_in">this</span>.clientList.push(fn)</span><br><span class="line">&#125;</span><br><span class="line">salesOffices.trigger = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;      <span class="comment">// 发布消息</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;<span class="built_in">this</span>.clientList.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> fn = <span class="built_in">this</span>.clientList[i]</span><br><span class="line">        fn.apply(<span class="built_in">this</span>,<span class="built_in">arguments</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">salesOffices.listen(<span class="function"><span class="keyword">function</span>(<span class="params">price,squareMeter</span>)</span>&#123;    <span class="comment">// 小明订阅消息</span></span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;m 价格= &#x27;</span>+price)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;m 平方= &#x27;</span>+squareMeter)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">salesOffices.listen(<span class="function"><span class="keyword">function</span>(<span class="params">price,squareMeter</span>)</span>&#123;    <span class="comment">// 小红订阅消息</span></span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;h 价格= &#x27;</span>+price)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;h 平方= &#x27;</span>+squareMeter)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">salesOffices.trigger(<span class="number">20000</span>,<span class="number">22</span>)      <span class="comment">// m/h 价格= 20000  m/h 平方= 22</span></span><br></pre></td></tr></table></figure>
<p>我们看到订阅者接收到了发布者发布的每个消息，虽然小明只想买 88 平方米的房子，但是发布者把 122 平方米的信息也推送给了小明，这对小明来说是不必要的困扰。所以我们有必要增加一个标示 key，让订阅者只订阅自己感兴趣的消息。改写后的代码如下：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> salesOffices = &#123;&#125;   <span class="comment">// 售楼处</span></span><br><span class="line">salesOffices.clientList = []    <span class="comment">// 缓存列表，存放订阅者的回调函数</span></span><br><span class="line">salesOffices.listen = <span class="function"><span class="keyword">function</span>(<span class="params">key,fn</span>)</span>&#123;     <span class="comment">// 增加订阅者</span></span><br><span class="line">    <span class="keyword">if</span>(!<span class="built_in">this</span>.clientList[key])&#123;      <span class="comment">// 如果没有订阅此类消息，给该类创建一个缓存列表</span></span><br><span class="line">        <span class="built_in">this</span>.clientList[key] = []</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">this</span>.clientList[key].push(fn)</span><br><span class="line">&#125;</span><br><span class="line">salesOffices.trigger = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;      <span class="comment">// 发布消息</span></span><br><span class="line">    <span class="keyword">var</span> key = <span class="built_in">Array</span>.prototype.shift.call(<span class="built_in">arguments</span>)     <span class="comment">// 取出消息类型 &lt;=&gt; arguments[0]</span></span><br><span class="line">    <span class="keyword">var</span> fns = <span class="built_in">this</span>.clientList[key]      <span class="comment">// 取出该消息对应的回调函数集合</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;fns.length;i++)&#123;</span><br><span class="line">        <span class="keyword">var</span> fn = fns[i]</span><br><span class="line">        fn.apply(<span class="built_in">this</span>,<span class="built_in">arguments</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter88&#x27;</span>,<span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;m 价格= &#x27;</span>+price)</span><br><span class="line">&#125;)</span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter88&#x27;</span>,<span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;w 价格= &#x27;</span>+price)</span><br><span class="line">&#125;)</span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter122&#x27;</span>,<span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;h 价格= &#x27;</span>+price)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">salesOffices.trigger(<span class="string">&#x27;squareMeter88&#x27;</span>,<span class="number">2200</span>)  <span class="comment">// m/w 价格= 2200</span></span><br><span class="line">salesOffices.trigger(<span class="string">&#x27;squareMeter122&#x27;</span>,<span class="number">122000</span>)   <span class="comment">// h 价格= 122000</span></span><br></pre></td></tr></table></figure>

<h2 id="发布-订阅模式的通用实现"><a href="#发布-订阅模式的通用实现" class="headerlink" title="发布-订阅模式的通用实现"></a>发布-订阅模式的通用实现</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 把发布-订阅功能提取出来，放在一个单独的对象内</span></span><br><span class="line"><span class="keyword">var</span> event = &#123;</span><br><span class="line">    clientList : [],</span><br><span class="line">    listen : <span class="function"><span class="keyword">function</span>(<span class="params">key,fn</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!<span class="built_in">this</span>.clientList[key])&#123;</span><br><span class="line">            <span class="built_in">this</span>.clientList[key] = []</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">this</span>.clientList[key].push(fn)</span><br><span class="line">    &#125;,</span><br><span class="line">    trigger: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> key = <span class="built_in">Array</span>.prototype.shift.call(<span class="built_in">arguments</span>)</span><br><span class="line">        <span class="keyword">var</span> fns = <span class="built_in">this</span>.clientList[key]</span><br><span class="line">        <span class="keyword">if</span>(!fns || fns.length===<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;fns.length;i++)&#123;</span><br><span class="line">            <span class="keyword">var</span> fn = fns[i]</span><br><span class="line">            fn.apply(<span class="built_in">this</span>,<span class="built_in">arguments</span>)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// installEvent 函数，给所有对象动态安装 发布-订阅功能：</span></span><br><span class="line"><span class="comment">// 浅拷贝 (我感觉 没什么用。。)</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">installEvent</span>(<span class="params">obj</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i <span class="keyword">in</span> event)&#123;</span><br><span class="line">        obj[i] = event[i]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> salesOffices = &#123;&#125;</span><br><span class="line">installEvent(salesOffices)</span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter88&#x27;</span>,<span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;price= &#x27;</span>+ price)</span><br><span class="line">&#125;)</span><br><span class="line">salesOffices.trigger(<span class="string">&#x27;squareMeter88&#x27;</span>,<span class="number">122</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="取消订阅事件"><a href="#取消订阅事件" class="headerlink" title="取消订阅事件"></a>取消订阅事件</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> event = &#123;</span><br><span class="line">    ...</span><br><span class="line">    remove: <span class="function"><span class="keyword">function</span>(<span class="params">key,fn</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> fns = <span class="built_in">this</span>.clientList[key]</span><br><span class="line">        <span class="keyword">if</span>(!fns)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(!fn)&#123;  <span class="comment">// 如果没有传入具体的回调函数，表示需要取消 key 对应消息的所有订阅</span></span><br><span class="line">            fns &amp;&amp; (fns.length = <span class="number">0</span>)</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="keyword">var</span> i=fns.length<span class="number">-1</span>;i&gt;=<span class="number">0</span>;i--)&#123;   <span class="comment">// 倒序删除</span></span><br><span class="line">                <span class="keyword">var</span> _fn = fns[i]</span><br><span class="line">                <span class="keyword">if</span>(_fn===fn)&#123;</span><br><span class="line">                    fns.splice(i,<span class="number">1</span>)</span><br><span class="line">                &#125; </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">...</span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter88&#x27;</span>,fn1 = <span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;f1 price= &#x27;</span>+ price)</span><br><span class="line">&#125;)</span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter88&#x27;</span>,fn2 = <span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;f2 price= &#x27;</span>+ price)</span><br><span class="line">&#125;)</span><br><span class="line">salesOffices.listen(<span class="string">&#x27;squareMeter88&#x27;</span>,fn1 = <span class="function"><span class="keyword">function</span>(<span class="params">price</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;f3 price= &#x27;</span>+ price)</span><br><span class="line">&#125;)</span><br><span class="line">salesOffices.remove(<span class="string">&#x27;squareMeter88&#x27;</span>,fn1)  <span class="comment">// 删除的是最后一个叫f1的订阅者</span></span><br><span class="line">salesOffices.trigger(<span class="string">&#x27;squareMeter88&#x27;</span>,<span class="number">122</span>) <span class="comment">// f1/f2 price= 122</span></span><br><span class="line"></span><br></pre></td></tr></table></figure> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
  </article>
  

  
  <nav class="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/4/">上一页</a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/3/">3</a><a class="page-number" href="/page/4/">4</a><span class="page-number current">5</span><a class="page-number" href="/page/6/">6</a><a class="page-number" href="/page/7/">7</a><a class="extend next" rel="next" href="/page/6/">下一页</a>
  </nav>
  
</section>
</div>

      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2019-2023
        <i class="ri-heart-fill heart_icon"></i> John Doe
      </li>
    </ul>
    <ul>
      <li>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>Visitors:<span id="busuanzi_value_site_uv"></span></s>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>Views:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/avatar.webp" alt="Doreen&#39;s Blog"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/about">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="Search">
        <i class="ri-search-line"></i>
      </a>
      
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    <div class="reward-item">
      <img class="reward-img" src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/alipay.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    
    
    <div class="reward-item">
      <img class="reward-img" src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/wechat.jpg">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
    
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>

<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->


<script src="/js/clickBoom2.js"></script>


<!-- CodeCopy -->


<link rel="stylesheet" href="/css/clipboard.css">

<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>


<!-- CanvasBackground -->


<script src="/js/dz.js"></script>



    
  </div>
</body>

</html>